?.은 ?. '앞’의 평가 대상이 undefined나 null이면 평가를 멈추고 undefined를 반환
obj?.prop – obj가 존재하면 obj.prop을 반환하고, 그렇지 않으면 undefined를 반환obj?.[prop] – obj가 존재하면 obj[prop]을 반환하고, 그렇지 않으면 undefined를 반환obj?.method() – obj가 존재하면 obj.method()를 호출하고, 그렇지 않으면 undefined를 반환?.은 ?. ‘앞’ 평가 대상에만 동작되고, 확장은 되지 않음
?.를 계속 연결해서 체인을 만들면 중첩 프로퍼티들에 안전하게 접근 가능
?.는 ?.왼쪽 평가대상이 없어도 괜찮은 경우에만 선택적으로 사용
let user = {};
alert(user.address.street); // TypeError: Cannot read property 'street' of undefined
// && 연산자를 사용한 경우
let user = {};
alert( user && user.address && user.address.street ); // undefined, 에러가 발생하지 않음
// 옵셔널 체이닝을 사용한 경우
let user = {};
alert( user?.address?.street ); // undefined, 에러가 발생하지 않음
alert( user.address?.street ); // undefined
?. 앞의 변수는 반드시 선언되어 있어야 함// ReferenceError: user is not defined
user?.address;
// 변수 user가 선언되어있지 않으면 user?.anything 평가시 에러가 발생
?.은 읽기나 삭제하기에는 사용할 수 있지만 쓰기에는 사용할 수 없음// SyntaxError: Invalid left-hand side in assignment
user?.name = "Violet";
// 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문
?.은 delete와 조합해 사용 가능delete user?.name; // user가 존재하면 user.name을 삭제
?.는 왼쪽 평가대상에 값이 없으면 즉시 평가를 멈춤?. 오른쪽에 있는 부가 동작은 ?.의 평가가 멈췄을 때 더는 일어나지 않음let user = null;
let x = 0;
user?.sayHi(x++); // 아무 일도 일어나지 않음
alert(x); // 0