출처: https://ko.javascript.info/logical-operators
논리 연산자
자바스크립트엔 세 종류의 논리 연산자 ||
(OR), &&
(AND), !
(NOT)이 있다. 연산자에 ‘논리’라는 수식어가 붙지만 논리 연산자는 피연산자로 불린형뿐만 아니라 모든 타입의 값을 받을 수 있다. 연산 결과 역시 모든 타입이 될 수 있다.
|| (OR)
전통적인 프로그래밍에서 OR 연산자는 불린값을 조작하는 데 쓰인다. 인수 중 하나라도 true
이면 true
를 반환하고, 그렇지 않으면 false
를 반환하는 것이다.
1
2
3
4
alert( true || true ); // true
alert( false || true ); // true
alert( true || false ); // true
alert( false || false ); // false
피연산자가 불린형이 아니면, 평가를 위해 불린형으로 변환된다. OR 연산자 ||
은 주어진 조건 중 하나라도 참
인지를 테스트하는 용도로 if
문에서 자주 사용된다.
첫 번째 truthy를 찾는 OR 연산자 ‘||’
자바스크립트에서만 제공하는 논리연산자 OR의 ‘추가’기능에 대해 알아보자.
OR 연산자와 피연산자가 여러 개인 경우:
1
result = value1 || value2 || value3;
이때, OR ||
연산자는 다음 순서에 따라 연산을 수행한다.
- 가장 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 피연산자를 평가한다.
- 각 피연산자를 불린형으로 변환한다. 변환 후 그 값이
true
이면 연산을 멈추고 해당 피연산자의 변환 전 원래 값을 반환한다. - 피연산자 모두를 평가한 경우(모든 피연산자가
false
로 평가되는 경우)엔 마지막 피연산자를 반환합니다.
여기서 핵심은 반환 값이 형 변환을 하지 않은 원래 값이라는 것이다.
OR "||"
연산자를 여러 개 체이닝(chaining) 하면 첫 번째 truthy를 반환한다. 피연산자에 truthy가 하나도 없다면 마지막 피연산자를 반환한다.
1
2
3
4
5
6
alert( 1 || 0 ); // 1 (1은 truthy임)
alert( null || 1 ); // 1 (1은 truthy임)
alert( null || 0 || 1 ); // 1 (1은 truthy임)
alert( undefined || null || 0 ); // 0 (모두 falsy이므로, 마지막 값을 반환함)
이런 OR 연산자의 추가 기능을 이용하면 여러 용도로 OR 연산자를 활용할 수 있습니다.
변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기
OR
||
을 사용하면 실제 값이 들어있는 변수를 찾고, 그 값을 보여줄 수 있다. 변수 모두에 값이 없는 경우(falsy)엔익명
를 보여준다.1 2 3 4 5
let firstName = ""; let lastName = ""; let nickName = "바이올렛"; alert( firstName || lastName || nickName || "익명"); // 바이올렛
단락 평가(short circuit evaluation)
위에서 설명해 드린 바와 같이 OR
||
은 왼쪽부터 시작해서 오른쪽으로 평가를 진행하는데, truthy를 만나면 나머지 값들은 건드리지 않은 채 평가를 멈춘다.단락 평가의 동작 방식은 두 번째 피연산자가 변수 할당과 같은 부수적인 효과(side effect)를 가지는 표현식 일 때 명확히 볼 수 있다.
1 2
true || alert("not printed"); // 출력X false || alert("printed"); // 출력
단락 평가는 연산자 왼쪽 조건이 falsy일 때만 명령어를 실행하고자 할 때 자주 쓰인다.
&& (AND)
전통적인 프로그래밍에서 AND 연산자는 두 피연산자가 모두가 참일 때 true
를 반환하고, 그 외에는 false
를 반환한다.
1
2
3
4
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
OR 연산자와 마찬가지로 AND 연산자의 피연산자도 타입에 제약이 없다.
첫 번째 falsy를 찾는 AND 연산자 ‘&&’
AND 연산자 &&
는 아래와 같은 순서로 동작한다.
- 가장 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 피연산자를 평가한다.
- 각 피연산자는 불린형으로 변환된다. 변환 후 값이
false
이면 평가를 멈추고 해당 피연산자의 변환 전 원래 값을 반환한다. - 피연산자 모두가 평가되는 경우(모든 피연산자가
true
로 평가되는 경우)엔 마지막 피연산자가 반환된다.
AND 연산자는 첫 번째 falsy를 반환한다. 피연산자에 falsy가 없다면 마지막 값을 반환한다. 위 알고리즘은 OR 연산자의 알고리즘과 유사하다. 차이점은 AND 연산자가 첫 번째 falsy를 반환하는 반면, OR은 첫 번째 truthy를 반환한다는 것이다.
1
2
3
4
5
6
7
8
9
// 첫 번째 피연산자가 truthy이면,
// AND는 두 번째 피연산자를 반환한다.
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// 첫 번째 피연산자가 falsy이면,
// AND는 첫 번째 피연산자를 반환하고, 두 번째 피연산자는 무시한다.
alert( null && 5 ); // null
alert( 0 && "아무거나 와도 상관없습니다." ); // 0
AND 연산자에도 피연산자 여러 개를 연속해서 전달할 수 있다.
1
alert( 1 && 2 && null && 3 ); // null
AND 연산자의 피연산자가 모두 truthy이기 때문에 마지막 피연산자가 반환된다.
1
alert( 1 && 2 && 3 ); // 마지막 값, 3
&&
의 우선순위가 ||
보다 높다.
따라서 a && b || c && d
는 (a && b) || (c && d)
와 동일하게 동작한다.
**if 를 | 나 &&로 대체하지 말자.** |
어떤 개발자들은 AND 연산자 &&
를 if
문을 ‘짧게’ 줄이는 용도로 사용하곤 한다.
1
2
3
4
5
6
let x = 1;
(x > 0) && alert( '0보다 큽니다!' );
// 왼쪽 피연산자 평가 후 참이면 오른쪽 피연산자 실행
if (x > 0) alert( '0보다 큽니다!' ); //이 if문과 같다.
&&
를 사용한 코드가 더 짧긴 하지만 if
문을 사용한 예시가 코드에서 무엇을 구현하고자 하는지 더 명백히 드러내고, 가독성도 좋다. 그러니 if 조건문이 필요하면 if
를 사용하고 AND 연산자는 연산자 목적에 맞게 사용하자.
! (NOT)
NOT 연산자는 인수를 하나만 받고, 다음 순서대로 연산을 수행한다.
- 피연산자를 불린형(
true / false
)으로 변환한다. - 1에서 변환된 값의 역을 반환한다.
1
2
alert( !true ); // false
alert( !0 ); // true
NOT을 두 개 연달아 사용(!!
)하면 값을 불린형으로 변환할 수 있다.
1
2
alert( !!"non-empty string" ); // true
alert( !!null ); // false
내장 함수 Boolean
을 사용하면 !!
을 사용한 것과 같은 결과를 도출할 수 있다.
1
2
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
NOT
연산자의 우선순위는 모든 논리 연산자 중에서 가장 높기 때문에 항상 &&
나 ||
보다 먼저 실행된다.
과제
Q1. 다음 OR 연산의 결과는 무엇일까요?
아래 코드의 결과를 예측해 보세요.
1
alert( null || 2 || undefined );
해답: 2
Q2. OR 연산자의 피연산자가 alert 라면?
아래 코드의 결과를 예측해 보세요.
1
alert( alert(1) || 2 || alert(3) );
해답: alert 창에 1과 2가 출력된다.
alert 메서드는 값을 반환하지 않는다. 즉 alert(1)
은 undefined를 반환한다. undefined는 falsy이기 때문에 다음 피연산자를 평가한다. 2는 truthy이기 때문에 실행을 멈추고 2를 반환한다. 반환된 값 2는 바깥 alert의 피연산자가 되어 두 번째 알림창에 출력된다.
Q3. 다음 AND 연산의 결과는 무엇일까요?
아래 코드의 결과를 예측해 보세요.
1
alert( 1 && null && 2 );
해답: null 첫 번째 falsy 값 리턴
Q4. AND 연산자의 피연산자가 alert 라면?
아래 코드의 결과를 예측해 보세요.
1
alert( alert(1) && alert(2) );
해답: 알림창으로 1이 출력되고 undefined가 출력된다.
Q5. OR AND OR 연산자로 구성된 표현식
아래 코드의 결과를 예측해 보세요.
1
alert( null || 2 && 3 || 4 );
해답: 3이 출력된다.
연산자 우선순위 때문에 2&&3
이 먼저 평가된다. 마지막까지 truthy한 값이니 마지막 값인 3이 반화된다. 그리고 null || 3 || 4
를 평가한다. 3이 첫 truthy한 값이니 3을 반환한다.
Q6. 사이 범위 확인하기
age
(나이)가 14
세 이상 90
세 이하에 속하는지를 확인하는 if
문을 작성하세요.
해답:
1
if (age >= 14 && age <= 90)
Q7. 바깥 범위 확인하기
age
(나이)가 14
세 이상 90
세 이하에 속하지 않는지를 확인하는 if
문을 작성하세요.
답안은 NOT !
연산자를 사용한 답안과 사용하지 않은 답안 2가지를 제출해 주세요.
해답:
1
2
if (age >= 14 && age )
if (!(age <= 14 || age >= 90))
Q8. “if”에 관한 고찰
아래 표현식에서 어떤 alert
가 실행될까요?
if(...)
안에 표현식이 있으면 어떤 일이 일어날까요?
1
2
3
if (-1 || 0) alert( 'first' );
if (-1 && 0) alert( 'second' );
if (null || -1 && 1) alert( 'third' );
해답: first, third가 출력된다.
Q9. 로그인 구현하기
프롬프트(prompt)
대화상자를 이용해 간이 로그인 창을 구현해보세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
let userName = prompt("Who's there?");
if (userName == "Admin") {
password = prompt("Passwrod?")
if (password == "TheMaster")
alert("Welcome!");
else if (password == '' || password == null)
alert("Canceled.");
else
alert("Wrong password");
} else if (userName == '' || userName == null)
alert("Canceled");
else
alert("I don't know you");