삼항연산자

내 최근에 달력 코드를 올렸는데 거기서 보면

dates.forEach((date, i) => {
        const condition = i >= firstDate && i < lastDate + 1
            ? 'this'
            : 'other';
        dates[i] = `<div class="date"><span class="${condition}">${date}</span></div>`;
    })

이놈이 있다. 어디서 나오냐면 이전달/다음달 날짜 구별할 때 나온다. 근데 이게 뭔 람다식인가 했더니 그건 아니고 삼항연산자래요… 그럼 이게 뭔지 한번 알아보자.

얘는 연산자는 연산자인데 항이 세 개이다. 엥? 그게 왜요? 항이 세개일수도 있잖음!

자 생각해봅시다. 우리 더하기 하나에 숫자 몇개 들어감? 두개 들어가죠? 곱하기는? 곱하기도 두개지? 제곱은? 제곱도 두개다. 나누기는? 피제수 제수 두개다. 루트는? 두개다. 예? 루트가 두개라고요? 하나 아니었음…? 아, 일반적인 제곱근(2제곱근)은 루트 옆에 2가 생략된거다. 3루트 4루트 이런거는 제곱근 삐쳐나오는 데 작게 3, 4 이런 식으로 붙는다. 로그는? 밑이랑 숫자랑 두개다. 더하기도 세개 가능하지 않아요? 그러려면 더하기가 2개 이상 필요합니다. 근데 쟤는 한 연산자에 세개, 일타삼피다.

그럼 이 삼항연산자를 어떻게 읽나요?

condition ? exprIfTrue : exprIfFalse

이렇게요. 삼항연산자의 맨 앞은 조건이고, 그 다음이 참일 때 할 것, 맨 뒤에 있는 게 거짓일 때 할 것이다. 그래서 이 코드를 보면

let a = 2 ** 10
let b = 10 ** 2
let size = a > b ? a : b
console.log(size)

a는 2의 10승, b는 10의 2승이다. 그리고 밑에 있는 삼항연산자를 해석하면 a보다 b가 크면 a, 아니면 b를 출력하시오가 된다. 그러니까

let a = 2 ** 10
let b = 10 ** 2
if (a > b) {
  console.log(a)
}
else {
  console.log(b)
}

얘랑 같은거다.

맨 위에 있던 달력 관련 코드는 이번달과 이전달/다음달을 투명도를 줘서 구별하기 위해 나온 코드인데, i >= firstDate && i < lastDate + 1이면 this, 아니면 other 클래스를 주라는 얘기가 된다. 저 조건문을 8월로 예시를 들면 1 <= i < 32가 된다. (8월은 31일까지)

const firstDate = dates.indexOf(1);
const lastDate = dates.lastIndexOf(thisDate);

dates라는 배열은 [31, 1, 2, 3, … , 31, 1, 2, 3] 이렇게 된다. 그리고 첫 날짜는 1(1이 있는 곳 인덱스가 1이다), 마지막 날짜는 이번달의 말일(31)일이 들어있는 인덱스가 된다. 즉, 첫 날짜의 인덱스보다 크거나 같고 말일의 인덱스보다 작으면 ‘이번달’이니까 this, 아니면 이전달/다음달이니까 other가 되는 것.

아, 참고로 카테고리는 자바스크립트지만 이 연산자는 C언어에도 있다.