모던 JavaScript 튜토리얼을 따라가면서 정리합니다.
4.6. 옵셔널 체이닝 ‘?.”
옵셔널 체이닝(optional chaining) ?.
을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있다.
옵셔널 체이닝이 필요한 이유
undefined 값의 프로퍼티를 읽으려 할 때 에러 발생
1
2
let user = {}; // 주소 정보가 없는 사용자.
alert(user.address.street); // TypeError: Cannot read property 'street' of undefined
null 값의 프로퍼티를 읽으려 할 때 에러 발생
1
2
// 페이지에 존재하지 않는 요소 접근
let html = document.querySelector(".my-element").innerHTML;
이 문제를 해결하기 위해 기존에는 &&
를 사용하곤 했다.
1
2
let user = {};
alert( user && user.address && user.address.street ); // undefined, 에러가 발생하지 않는다.
옵셔널 체이닝
평가후 결과가 null
이나 undefined
가 아닌 경우 값이 ‘있다’, ‘존재한다’라고 표현한다.
user.address.street
에 안전하게 접근해보자.
1
2
let user = {}; // 주소 정보가 없는 사용자
alert (user?.address?.street); // undefined, 에러가 발생하지 않는다.
?.
은 ?.
‘앞’ 평가 대상에만 동작되고, 확장은 되지 않는다.
1
2
3
4
let user = null;
alert( user?.address ); // undefined
alert( user?.address.street ); // undefined
한편, ?.
는 존재하지 않아도 괜찮은 대상에만 사용해야 한다. 사용자 주소를 다루는 예시에서 논리상 user
는 반드시 있어야 하는데, address
는 필수값이 아니다. 그러니 user.address?.street
을 사용하는 것이 바람직하다.
?.
앞의 변수는 꼭 선언되어 있어야 한다. 변수 user
가 선언되어 있지 않다면 user?.anything
평가 시 에러가 발생한다.
옵셔널 체이닝은 선언된 변수에만 작동한다.
단락 평가
?.
은 왼쪽 평가 대상에 값이 없으면 즉시 평가를 멈추는 단락 평가(short-circuit)을 한다. 그렇기에 함수 호출을 비롯한 ?.
오른쪽에 있는 부가 동작은 ?.
의 평가가 멈췄을 때 더는 일어나지 않는다.
1
2
3
4
5
let user = null;
let x = 0;
user?.sayHi(x++); // 아무 일도 일어나지 않는다.
alert(x); // 0, x는 증가하지 않는다.
?.()
와 ?.[]
?.
는 연산자가 아니라 함수나 대괄호와 함께 동작하는 특별한 문법 구조체(syntax construct)이다.?.()
를 사용해 존재 여부를 확인하고 메서드를 호출한다.1 2 3 4 5 6 7 8 9 10
let user1 = { admin() { alert("관리자 계정입니다."); } } let user2 = {}; user1.admin?.(); // 관리자 계정입니다. user2.admin?.(); // 에러 없이 평가가 멈춘다.
?.[]
를 사용하면 객체 존재 여부가 확실치 않은 경우에도 안전하게 프로퍼티를 읽을 수 있다.1 2 3 4 5 6 7 8 9 10 11
let user1 = { firstName: "Violet" }; let user2 = null; //user2는 권한이 없는 사용자라고 가정해보자. let key = "firstName"; alert( user1?.[key] ); // Violet alert( user2?.[key] ); // undefined alert ( user1?.[key]?.something?.not?.existing ); // undefined
?.
은delete
와 조합해 사용할 수 있다.1
delete user?.name; //user가 존재하면 user.name을 삭제한다.
?.
은 읽기나 삭제하기에는 사용할 수 있지만 쓰기에는 사용할 수 없다.1 2
user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment // 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문이다.