논리연산자
자바스크립트에는 3종류의 논리연산자 | (OR), &&(AND), !(NOT) 이 있다. |
연산자에는 ‘논리’라는 수식어가 붙긴 하지만, 논리 연산자는 피연산자로 Boolean 형뿐만 아니라 모든 타입의 값을 받을 수 있다. 연산 결과 역시 모든 타입이 될 수 있다.
첫 번째 truthy 를 찾는 OR 연산자 ‘||’
보통 논리연산자를 Boolean 형인 경우만을 다뤘다. 자바스크립트에서만 제공하는 논리연산자 OR 의 ‘추가’ 기능에 대해 알아보자.
OR 연산자와 피연산자가 여러개인 경우:
1
const result = value1 || value2 || value3;
이때, OR 연산자는 다음 순서에 따라 연산을 수행한다.
- 가장 왼쪽 피연산자부터 시작해 오른쪽으로 가며 피연산자를 평가
- 각 피연산자를 불린형으로 변환한다. 변환 후 그 값이
true
이면 연산을 멈추고, 해당 피연산자의 변환 전 원래 값을 반환한다. - 피연산자 모두를 평가한 경우(모든 피연산자가
false
로 평가되는 경우)엔 마지막 피연산자를 반환한다.
여기서 핵심은 반환값이 형 변환을 하지 않은 원래 값이라는 것이다.
다음의 예시를 보자.
1
2
3
4
5
6
alert(1 || 0); // 1 (1은 truthy)
alert(null || 1); // 1
alert(null || 0 || 1); // 1
alert(undefined || null || 0); // 0 (모든 피연산자 결과값이 falsy 이므로, 마지막 값을 반환한다)
OR 연산자의 여러용도
변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기
firstName
,lastName
,nickName
이란 변수가 있는데, 이 값들을 모두 옵션값이라고 해보자.1 2 3 4 5
let firstName = ""; let lastName = ""; let nickName = "바이올렛"; alert(firstName || lastName || nickName || "익명"); // 바이올렛
모든 변수가 falsy 면 “익명”이 출력될 것이다.
단락 평가(short circuit evalutaion) 단락 평가란? truthy 를 만나면 나머지 값들은 건드리지 않은 채 평가를 멈추는 것.
단락 평가의 동작 방식은 두 번째 피연산자가 변수 할당과 같은 부수적인 효과(side effect)를 가지는 표현식 일 때 명확히 볼 수 있다.
아래 예시를 실행하면 두번째 얼럿만 출력된다.
1 2
true || alert("not priunted"); false || alert("printed");
첫번째 줄의 얼럿은
true
를 만나자 마자 평가를 멈추기 떄문에 얼럿 실행 x. 단락 평가는 연산자 왼쪽 조건이 falsy 일 때만 명령어를 실행하고자 할 때 자주 쓰인다. 정리를 하다가 느낀건데, 아마&&
연산자는 이에 반대겠지. true 일때만 명령어 실행하고자 할 때 쓰일 것이다.
첫 번째 falsy를 찾는 AND 연산자 ‘&&’
AND 연산자와 피연산자가 여러개인 경우를 살펴보자.
1
const result = value1 && value2 && value3;
AND 연산자 &&
는 아래와 같은 순서로 동작한다.
- 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 피연산자를 평가
- 피연산자는 불린형으로 변환. 변환 후 값이
false
이면 평가를 멈추고 해당 피연산자의 변환 전 원래 값을 반환한다. - 피연산자 모두가 평가되는 경우(모든 피연산자가
true
로 평가되는 경우)엔 마지막 피연산자가 반환됨.
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
주의할 점
!
>&&
>||
우선순위는 NOT > AND > OR 순이다. 수학 연산자에서 곱하기나 나누기가 먼저 실행되는 것과 같은 원리다.
if
를||
나&&
로 대체하지 마!간혹 코드량을 줄이기 위해
if
문을 논리연산자로 대체하는 경우가 있다. 하지만if
문을 사용한 예시가 코드에서 무엇을 구현하고자 하는지 더 명백히 드러나고, 가독성도 좋다. 연산자는 연산자 목적에 맞게 사용하자.
내가 사용한 논리연산자
- 간결한 코드가 요구되는 jsx
1 2 3 4 5 6 7
{ Order?.PaymentDate && ( <DescriptionsItemGreyText>{`처리일 ${timeFormatter( Order?.PaymentDate ).substring(0, 11)}`}</DescriptionsItemGreyText> ); }
jsx 에서는 if문을 사용하기 어렵다. 따라서 삼항연산자로 작성해야 하는 경우가 많은데, 이때 논리연산자를 사용하면 편하다.
어떤 조건 이후 함수를 실행해야 하는 경우. 다음과 같은 예시를 보자.
1 2 3 4 5
useEffect(() => { !OrderSiteLists?.length && !GetOrderSitesListsError && dispatch(GetOrderSitesLists(null)); }, [OrderSiteLists, GetOrderSitesListsError]);
&&
연산자가 2회 사용되었다. length 가 없고, get 요청 보낸 api 의 에러가 없을때만 dispatch 함수가 실행되도록 작성했다. 이것을 if 문으로 작성하면 좀더 직관적일까? 가끔은 논리연산자로 하는 것이 더 직관적으로 보일때가 있는것 같다(왜냐? 변수로 비교하는 것이기 때문에 짧다)if 문 안에서 모든 조건을 만족하는 경우 혹은 그중에 하나만이라도 만족하는 경우
1
if (isGiftEdit && isGiftDrawerVisible && StoreProductIDSyncLists)
모두 true 인 경우에만 if 문이 실행될 것이다. 이거를 조건문으로 표현하면 depth 가 상당히 깊어지고, 오히려 가독성이 떨어질 것 같다는 생각이 든다.