1. 단축평가
1.1 논리 연산자를 사용한 단축평가
논리합(||) 또는 논리곱 (&&) 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로 평가됩니다.
1.1.1 논리곱( && ) 연산자
1'Cat' && 'Dog' // "Dog"
논리곱(&&) 연산자는 두 개의 피연산자가 모두 true로 평가될 때 true를 반환하며, 좌항에서 우항으로 평가가 진행됩니다.
첫 번째 피연산자 ‘Cat’은 Truthy 값이므로 true로 평가됩니다. 하지만 위 표현식은 이 시점에서 평가할 수 없습니다.
두 번째 피연산자까지 평가해야합니다.
즉, 두 번째 피연산자가 논리곱 연산자 표현식의 평가 결과를 결정하며, 두 번째 피연산자 ‘Dog’를 그대로 반환합니다
1.1.2 논리합( || ) 연산자
1'Cat' || 'Dog' // "Cat"
논리합(||) 연산자는 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환하며, 좌항에서 우항으로 평가가 진행됩니다.
첫 번째 피연산자 ‘Cat’은 Truthy 값이므로 true로 평가됩니다.
이 시점에 두 번째 피연산자까지 평가하지 않아도 표현식을 평가할 수 있습니다.
논리합 연산자는 논리 연산의 결과를 결정한 첫 번째 피연산자, 문자열 ‘Cat’을 그대로 반환합니다.
1.2 단축 평가란?
&& 연산자와 || 연산자는 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는데, 이를 단축 평가라고 합니다.
단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말합니다.
단축 평가는 다음의 규칙을 따릅니다.
1true || anything // true2false || anything // anything3true && anything // anything4false && anything // false
2. undefined, null 체크
undefined: 값이 있는지 없는지 모름null: 값이 없음
2.1 일반적인 undefined 체크
특정 값이 undefined 인지를 체크하기 위해서는
1var a2console.log(typeof a == 'undefined') // true3console.log(a == undefined) // true
2.2 일반적인 null 체크
null 인지를 체크하기 위해서는
1var b = null2console.log(b == null) // true
위와 같이 정확하게 값을 체크하는데 사용될 수 있다.
2.3 간단하게 undefined, null 체크
하지만, undefined와 null은 논리연산에서는 false로 처리되므로 아래처럼 간단하게 체크하면 되겠다.
1var a2console.log(a) // undefined3console.log(!a) // true4// if (a) {}5// if (!a) {}67var b = null8console.log(b) // null9console.log(!b) // true10// if (b) {}11// if (!b) {}
undefined와 null을 철저히 체크하는 경우가 아니라면, if (!a) {}처럼 간단히 사용하면 되겠다.
1if (a != undefined && a != null) {2}3if (a != undefined && !a) {4}
위 두가지 모두 if (!a) {} 와 동일하다.
3. undefined, null 체크 예시
예시 1 : if문 파라미터의 값이 비어있는지
1let nIntervId23function changeColor() {4// check if an interval has already been set up5// nIntervId이 null이거나 undfined 이라면, (=값이 없다면)6if (!nIntervId) {7nIntervId = setInterval(flashText, 1000)8}9}
예시 2 : 배열 길이가 0인지 판단
1if ( array.length === 0 ) // 💩 Bad2if ( !array.length ) // array.length 값이 없다면, 👍 Good
예시 3 : 배열 길이가 0보다 큰지 판단
1if ( array.length > 0 ) // 💩 Bad2if ( array.length ) // 👍 Good
array.length > 0이 로직은 array.length의 특성상 음수값은 존재하지 않고 양수값만 존재하게된다.
그러므로 0이냐 0이 아니냐로 판단이 가능하다.
예시 4: 문자열이 비어있는지 판단
1if ( string === "" ) // 💩 Bad2if ( !string ) // 👍 Good
빈문자열은 조건문안에서 false이다. 빈문자열임을 확인하고 싶으면 부정(!)을 더해서 false -> true로 만들어주면 된다.
예시 5 : 문자열이 값이 있는지 판단
1if ( string !== "" ) // 💩 Bad2if ( string ) // 👍 Good
빈문자열은 조건문안에서 false이다. 그러므로 빈문자열이 아닐때를 판별할때는 빈문자열이 들어올 변수를 조건문안에 넣어주기만 하면된다.
예시 6 : 삼항 조건 연산자
1let done = true2let message = ''34//if...else문5if (done) message = '완료'6else message = '미완료'7console.log(message) //완료89message = done ? '완료' : '미완료'10console.log(message) //완료
4. 옵셔널 체이닝 ?.
- 좌항의 피연산자가
null또는undefined인 경우undefined를 반환하고, - 그렇지 않으면 우항의 프로퍼티 참조를 이어갑니다.
- ES11에서 도입(ECMAScript 2020)
- cf. MDN 옵셔널 체이닝
1let elem = null23// elem이 null또는 undefined이면 undefined 반환, 그렇지 않으면 우항의 프로퍼티 참조를 이어감4let value = elem?.value5console.log(value) // undefined
?.는 객체를 가리키기를 기대하는 변수가 null또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때 유용합니다.
?.가 도입되기 전에는 논리 연산자 &&를 사용한 단축 평가를 통해 변수가 null 또는 undefined인지 확인했습니다.
1let elem = null23// elem이 Falsy 값이면 elem으로 평가, elem이 Truthy 값이면 elem.value로 평가4let value = elem && elem.value5console.log(value) // null
논리 연산자 &&는
- 좌항 피연산자가 false로 평가되는
Falsy 값(false, undefined, null, 0, -0, NaN, '')이면 - 좌항 피연산자를 그대로 반환합니다.
1let str = ''23let length = str && str.length45// 문자열의 길이를 참조하지 못함6console.log(length) // ''
하지만 옵셔널 체이닝 연산자?.는
- 좌항 피연산자가 false로 평가되는 Falsy 값이라도
null또는undefined가 아니면 - 우항의 프로퍼티 참조를 이어갑니다.
1let str = ''23let length = str?.length4console.log(length) // 0
4.1 예제
1// 옵셔널 체이닝 연산자 (Optional Chaining Operator)2// null 또는 undefined을 확인할때3let item = { price: 1 }4// const price = item && item.price;를 옵셔널 체이닝 연산자로 표현5const price = item?.price6console.log(price) // 178let obj = { name: '🐶', owner: { name: '메시' } }9function printName(obj) {10// 📝 obj 오브젝트가 있다면, owner가 있다면, name이 있다면11// owner가 없다면 undefined, name이 없다면 undefined12const ownerName = obj?.owner?.name13console.log(ownerName) // 메시14}15printName(obj)
5. null 체크하는 깔끔한 법⭐
5.1 null 병합 연산자 ??
ES11에서 도입된 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고,
그렇지 않으면 좌항의 피연산자를 반환합니다.
cf. MDN null 병합연산자(Nullish Coalescing Operator)
1let foo = null ?? 'default string'2console.log(foo) // "default string"
??는 변수에 기본값을 설정할 때 유용합니다.
??가 도입되기 전에는 논리 연산자 ||를 사용한 단축 평가를 통해 변수에 기본값을 설정했습니다.
논리 연산자 ||를 사용한 단축 평가의 경우 좌항의 피연산자가 false로 평가되는 Falsy 값이면 우항의 피연산자를 반환합니다.
만약 Falsy 값인 0이나 ''도 기본값으로 유효하다면 예기치않은 동작이 발생할 수 있습니다.
1let foo = '' || 'default string'2console.log(foo) // "default string"
하지만 ??는 좌항의 연산자가 false로 평가되는 Falsy 값이라도 null 또는 undefined가 아니면,
좌항의 피연산자를 그대로 반환합니다.
1let foo = '' ?? 'default string'2console.log(foo) // ""
5.2 예제
1// 📝 ?? 연산자 : null, undefined에만2// 📝 || : falshy한 경우 설정(할당) 0, -0, ''3let num = 045// num의 값이 없을 때만, -1을 출력하고 싶을 떄6console.log(num || '-1') // 0은 falshy에 해당되어 -1이 출력7console.log(num ?? '-1') // 0