옵셔널 체이닝 '?'

김하은·2023년 5월 7일
0

옵셔널 체이닝 ?.를 사용함다면 프로퍼티가 없는 중첩객체를 에러 없이 접근하는것이 가능하다.

옵셔널 체이닝의 필요성

사용자가 여러명 있고 이들의 주소정보를 가지는 객체가 있다.
그러나 몇명은 주소 정보가 없다.
이럴때 주소정보에 접근한다면 에러가 발생할 수도 있다.

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"이 되기 때문입니다.

0개의 댓글