옵셔널 체이닝 ?.
를 사용함다면 프로퍼티가 없는 중첩객체를 에러 없이 접근하는것이 가능하다.
사용자가 여러명 있고 이들의 주소정보를 가지는 객체가 있다.
그러나 몇명은 주소 정보가 없다.
이럴때 주소정보에 접근한다면 에러가 발생할 수도 있다.
et user = {}; // 주소 정보가 없는 사용자
alert(user.address.street); // TypeError: Cannot read property 'street' of undefined
또는 자바스크립트를 사용해 페이지에 존재하지 않는 요소에 접근해 요소의 정보를 가져오려할 경우 문제가 발생할 수 있다.
// querySelector(...) 호출 결과가 null인 경우 에러 발생
let html = document.querySelector('.my-element').innerHTML;
이전에는 이러한 문제 해결을 위해 &&
연산자를 사용하였다.
console.log(user && user.address && user.address.street)
중첩객체의 특정 프로퍼티에 접근하기 위해 거치는 각 요소를 &&
로 연결해 실제로 있는지 확인하는 방법이다.
그런데 이런방식을 사용하다보면 보다시피 코드가 아주 길어진다.
그러다가 옵셔널 체이닝이라는 것이 등장하게 되었다.
옵셔널 체이닝은 ?
앞의 평가 대상이 undefined나 null 이면 평가를 멈추고 undefined를 반환한다.
주의:
- 옵셔널 체이닝 남용금지
?.
는 존재하지 않더라도 문제없는 대상에만 사용해야한다.
반드시 있어야하는 곳에는 사용하지 않아야 디버깅이 쉬워진다.
?.
앞의 변수는 꼭 선언되어 있어야한다.?.
는 왼쪽 평가대상(앞쪽)에 값이 없다면 즉시 평가를 멈춘다.
이런 방법을 단락평가(short-circuit)라고 한다.
때문에 함수 호출을 비롯한 ?.
의 오른쪽(뒷쪽)에 있는 부가동작은 ?.
의 평가가 멈췄을때 더는 일어나지 않는다.
?.
는 연산자가 아니라 함수나 대괄호와 함께 동작하는 특별한 문법구조체이다.
let user1 = {
admin() {
alert("관리자 계정입니다.");
}
}
let user2 = {};
user1.admin?.(); // 관리자 계정입니다.
user2.admin?.();
두 상황에서 모두 user라는 것은 있으니 이후 admin에 ?.()
를 통해 admin의 존재여부를 확인한다.
user1에는 admin이 있어 메서드가 제대로 호출되었고,
user2에는 admin이 없는데도 메서드를 호출하면 에러없이 단지 평가가 멈춘다.
. 대신에 대괄호를 사용해 같은 방식을 사용할 수 있다.
?.[]
를 사용하면 객체의 존재여부가 확실치 않은 경우에도 안전하게 프로퍼티를 읽을 수 있다.
?.은 delete와 조합해 사용할 수도 있다.
delete user?.name; // user가 존재하면 user.name을 삭제
?.
는 읽기나 삭제하기에는 사용이 가능하나 쓰기에는 사용이 불가하다.// user가 존재할 경우 user.name에 값을 쓰려는 의도로 아래와 같이 코드를 작성해 보았습니다.
user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment
// 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문입니다.