논리연산자를 활용한 단축 평가

논리합 / 논리곱 연산자

우리는 학창 시절 집합을 배우면서 합집합과 교집합을 통해 논리합과 논리곱에 대한 감을 잡았고, 이후 이산 수학을 통해 두 명제에 대한 논리 연산으로 이해를 확장시켰습니다.

  • 논리합 (A or B)
    A와 B의 각 명제 중 하나라도 ‘참’일 경우 두 명제의 논리합은 ‘참’이 된다.
    (두 명제 모두 ‘거짓’일 때만 논리합이 ‘거짓’이 된다.)

  • 논리곱 (A and B)
    A와 B의 각 명제가 모두 ‘참’일 때만 논리곱은 ‘참’이 된다.
    (두 명제 중 하나라도 ‘거짓’일 경우 논리곱은 ‘거짓’이 된다.)

자바스크립트의 논리 연산도 동일한 원리로 동작합니다.

1
2
3
4
5
const testTrue = true;
const testFalse = false;

console.log(testTrue || testFalse); // output: true
console.log(testTrue && testFalse); // output: false

논리합 / 논리곱을 사용한 단축 평가

자바스크립트 동작에서 우리가 주목할 특징은 “논리 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로만 평가된다.” 라는 점입니다. 그리고 논리 연산의 결과를 결정한 대상을 타입 변환없이 그대로 반환하게 됩니다.

이 때 평가의 결과가 확정되었다면, 나머지 평가 과정을 생략하게 되는데 이를 단축평가 라고 합니다.

논리합 연산자의 평가 대상 (A || B)

논리합 연산자는 두 피연사자 중 하나만 true여도 true를 반환합니다. 따라서 앞의 항 A의 값이 true라면 위에 말한 단축 평가의 동작 원리대로 나머지 평가 과정을 멈추고 A를 평가한 값을 그대로 반환하게 됩니다.
반환 결과: 평가된 A

만약 A의 값이 false라면 논리합의 결과를 알기 위해서는 B의 값을 평가해야 합니다. B가 false라면 false를 반환, B가 true라면 true를 반환하게 됩니다. 즉 논리 연산의 결과는 B의 값에 따라 결정됩니다.
반환 결과: 평가된 B

이를 활용하여 저희는 A의 평가 결과를 조건으로 반환 대상을 결정하는 코드를 if else문을 대체하여 표현식으로 사용할 수 있습니다.

1
2
3
4
// react
{
!dirty || error ? <small>'Error'</small> : null;
}

위 코드는 dirty의 값이 ‘참’일 때만 error 여부를 판별하여 error가 ‘참’일 경우 ‘Error’ 문자열을 렌더링하는 코드입니다. dirty의 값이 ‘거짓’일 경우 error 여부와 관계없이 ‘Error’ 문자열을 렌더링합니다.

*null 병합 연산자 (A ?? B)

논리합 연산자를 사용할 때 주의할 점은 연산자가 각 피연산자의 Truthy / Falsy 값을 판단한다는 점입니다. 위 논리합 연산자의 예시에서 dirty값이 string 데이터 타입이라고 가정해봅시다.

개발자가 빈 문자열 또한 dirty 값이 있다고 가정 한다해도 빈 문자열 ‘’은 Falsy 값으로 판단되어 자바스크립트는 B를 평가하게 됩니다. 이것은 개발자의 의도대로 동작한 것이 아닙니다.

Truty / Falsy 값을 판별하는게 아니라 값 자체가 할당되지 않았거나(undefined) 명시적으로 빈 값이라고 표현된 요소(null)를 판단하고 싶다면 null 병합 연산자 를 사용할 수 있습니다. null 병합 연산자를 사용하면 피연산자가 null 또는 undefined인지 여부만을 판단하게 됩니다.

1
2
3
4
// react
{
!dirty ?? error ? <small>'Error'</small> : null;
}

논리곱 연산자의 평가 대상 (A && B)

논리곱 연산자는 두 피연산자가 모두 true일 경우만 true를 반환합니다. 따라서 앞의 항의 값이 false라면 위에 말한 단축 평가의 동작 원리대로 나머지 평가 과정을 멈추고 A를 평가한 값을 그대로 반환하게 됩니다.
반환 결과: 평가된 A

만약 A의 값이 true라면 논리곱 연산자의 결과를 알기 위해서는 B의 값을 평가해야 합니다. B가 true라면 true를 반환 B가 false라면 false를 반환하게 됩니다. 즉 논리 연산의 결과는 B의 값에 따라 결정됩니다.
반환 결과: 평가된 B

논리합 연산자와 마찬가지로 A의 평가 결과를 조건으로 반환 대상을 결정하는 코드를 if else문을 대체하여 표현식으로 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
// react
// dirty 값이 '참'일 경우에만 remove 버튼을 렌더링
{
dirty && (
<button type="button" className={styles.removeBtn} onClick={resetEmail} tabIndex={-1}>
<InputRemove className={styles.removeBtn__icon} />
</button>
);
}

옵셔널 체이닝 연산자

옵셔널 체이닝 연산자는 자바스크립트의 메서드 체이닝 여부를 대상 객체의 평가 결과에 따라 결정할 수 있는 방법입니다.

1
2
3
4
// react
const data = axios.get('http://test/posts.com') // [element1,element2,...]
// ... 생략
{data.forEach((el)=> ...)}

위 코드의 경우 만약 http 요청으로 받아온 data의 값이 없을 경우 에러를 출력하여 페이지 렌더링이 불가능합니다. 만약 data가 있을 경우 해당 요소를 렌더링하고, 없다면 저 부분만을 제외한 상태로 정상적인 렌더링을 하기 위해 옵셔널 체이닝 연산자를 활용할 수 있습니다.

1
2
3
4
// react
const data = axios.get('http://test/posts.com') // null / undefined
// ... 생략
{data?.forEach((el)=> ...)}

옵셔널 체이닝 연산자를 사용하면 data의 값이 null이나 undefined인 경우에는 forEach 메서드를 실행하지 않고, 평가를 종료합니다.