옵셔널 체이닝은 property가 없는 중첩 객체를 접근할 때 발생하는 오류를 막아주는 용도로 쓰인다.
옵셔널 체이닝이 쓰이기 전엔 이러한 오류가 가능했다.
let user = {}; // 주소 정보가 없는 사용자
alert(user.address.street); // TypeError: Cannot read property 'street' of undefined
let html = document.querySelector('.my-element').innerHTML;
// .my-element가 없으면 에러 발생
위와 같은 에러를 해결하기 위해 처음엔 &&
을 사용했다.
let user = {};
alert( user && user.address && user.address.street ); // undefined
A ?. B
?.
의 앞에 오는 대상이 undefined나 null 일 경우, 평가를 멈추고 undefined를 반환한다. user.address.street
를 user?.address?.street
로 접근할 경우, address가 존재하지 않기 때문에 street을 평가하기 전에 undefined를 반환하며 에러 발생을 막는다. 예시 :
let user = null;
alert( user?.address ); // undefined
alert( user?.address.street ); // undefined
위의 예시의 경우, 가장 상단의 객체인 user가 null이기 때문에,
user?.
의 평가에서 바로 undefined가 반환되며 평가가 종료된다.
💡
?.
는 존재하지 않아도 되는 대상에만 사용하자!
꼭 존재해야 하는 대상은, 존재하지 않음을 에러로 빠르게 발견해야 하기 때문이다
💡
?.
의 앞 대상이 null이나 undefined일때 undefined를 반환해주는 것이다. 따라서 앞의 대상이 아예 선언되지 않은 경우엔 에러가 발생한다.
?.
의 앞쪽 대상이 null, undefined일 때 평가를 종료한다고 했다.
이 뜻은 평가가 종료되면 오른쪽의 남은 내용들은 평가되지 않는다는 뜻이다.
예시 :
let user = null;
let x = 0;
user?.sayHi(x++); // user가 null이므로 평가 종료. 오른쪽 평가 X
alert(x); // 0 출력, x는 증가하지 않았기 때문에.
이렇게 왼쪽의 평가 대상의 결과를 보고, 결과에 따라 평가를 멈춰서 오른쪽은 실행하지 않는 방식을 단락 평가(short-circuit) 이라고 한다.
본문에 한번도 '연산자', '피연산자'라는 단어가 사용되지 않았다.
그 이유는 ?.
는 연산자가 아닌, 특별한 문법 구조체이기 때문이다.
?.
의 오른쪽엔 괄호, 대괄호가 올 수 있는데, 어떠한 경우에 사용되는지 살펴보자.
함수명?.()
함수명()
은 함수가 존재하지 않을 경우 에러가 발생한다. 객체명.키
-> 객체명?.키
로 옵셔널 체이닝을 적용했다. 객체명[키]
-> 객체명?.[키]
로 옵셔널 체이닝을 적용한다. 표기법의 차이이지, 하는 역할은 ?.와 동일하다
형태 :
// 기존 객체 property 삭제 방식
delete 객체명.키;
// 옵셔널 체이닝 활용
delete 객체명?.키;
옵서녈 체이닝을 활용하면, 객체명에서 지정한 객체가 존재할 때만 키를 삭제하는 행위가 발생하기 때문에 에러를 방지할 수 있다.
💡
?.
는 할당연산자의 왼쪽에서 쓰일 수 없다.
즉, 객체의 property를 '수정'할 땐 사용할 수 없다.
예시 :user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment // 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문입니다.
할당 연산자의 왼쪽에 undefined가 오는 것이 불가능하기 때문에 에러가 발생한다.