자바스크립트에서 논리합 연산(||)과 논리곱 연산(&&)의 결과값은 boolean 타입이 아닐 수 있다

뉴우비(newwwbi)·2023년 3월 4일

TIL

목록 보기
2/10
post-thumbnail

불 대수에서 논리 연산의 입력값과 출력값은 모두 참(1, T, True) 또는 거짓(0, F, False)이다.
마찬가지로 대부분의 프로그래밍 언어에서도 논리 연산의 결과값은 참(true) 또는 거짓(false)이다.
그런데 자바스크립트에서는 논리합 연산과 논리곱 연산의 결과값이 참과 거짓 둘 다 아닐 수 있다.
자바스크립트에서 논리합 연산과 논리곱 연산이 약간 다른 방식으로 동작하기 때문이다.

논리합 연산(||)

예를 들어, 이런 코드가 있을 때

const result = value1 || value2 || value3;

논리합 연산은 다음과 같은 순서대로 수행된다.

  • 가장 왼쪽 피연산자(=value1)부터 시작해서 오른쪽으로 진행하며 차례대로 피연산자를 검사한다.
  • 값이 truthy 한(= falsy 하지 않은) 피연산자를 찾으면, 연산을 멈추고 해당 피연산자 값을 반환한다.
  • 모든 피연산자의 값이 falsy 하면, 마지막 피연산자(=value3)를 반환한다.

예시

console.log('HELLO' || 'WORLD' || '~!'); // 출력 결과: 'HELLO'
console.log(0 || 1 || 2);                // 출력 결과: 1
console.log(false || 0 || '');           // 출력 결과: ''
console.log(null || undefined || NaN);   // 출력 결과: NaN

논리곱 연산(&&)

예를 들어, 이런 코드가 있을 때

const result = value1 && value2 && value3;

논리곱 연산은 다음과 같은 순서대로 수행된다.

  • 가장 왼쪽 피연산자(=value1)부터 시작해서 오른쪽으로 진행하며 차례대로 피연산자를 검사한다.
  • 값이 falsy 한 피연산자를 찾으면, 연산을 멈추고 해당 피연산자 값을 반환한다.
  • 모든 피연산자의 값이 truthy 하면, 마지막 피연산자(=value3)를 반환한다.

예시

console.log(null && 'HELLO' && 'WORLD'); // 출력 결과: null
console.log(true && undefined && null);  // 출력 결과: undefined
console.log(true && 1 && 'HI')           // 출력 결과: 'HI'
console.log(1 && [] && {})               // 출력 결과: {}

주의해야 될 점

사실 이런 자바스크립트의 독특한(?) 동작 방식을 몰라도 대부분의 케이스에서는 큰 문제가 없다.
그런데 함수의 반환값으로 논리합 연산이나 논리곱 연산의 결과값을 그대로 리턴하는건 숨겨진 버그를 만들 가능성이 있는거 같다.

예를 들어,
age parameter 값이 null 이나 undefined 가 아니고 17보다 크면 true, 그렇지 않으면 false를 반환하는 isAdult 함수가 있을 때, 아래와 같이 논리곱 연산의 결과값을 그대로 리턴하도록 함수를 리팩토링하면

// before
function isAdult(age) {
  if (age && age > 17) {
   	return true;
  } else {
    return false;
  }
}

// after
function isAdult(age) {
  return age && age > 17;
}

isAdult 함수의 반환값이 false 인지 strict equal 비교 연산하는 곳이 있을 때 프로그램이 의도와 다르게 동작하게 만들 수 있다.

const person = {
	name: 'newwwbi',
  	age: null,
};

// isAdult 함수의 반환값은 null 이기 때문에 해당 if문은 실행되지 않는다.
if (isAdult(person.age) === false) { 
  throw new Error('He is not an adult!');
}

// ... 이하 생략 ...

참고 자료

https://ko.javascript.info/logical-operators
https://mygumi.tistory.com/33

profile
배운 지식을 다른 사람과 공유하고 싶습니다

0개의 댓글