Posts 모던 자바스크립트 #4.6. 옵셔널 체이닝 '?.'
Post
Cancel

모던 자바스크립트 #4.6. 옵셔널 체이닝 '?.'

모던 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"이 되기 때문이다.
    
This post is licensed under CC BY 4.0 by the author.

모던 자바스크립트 #4.5 new 연산자와 생성자 함수

모던 자바스크립트 #4.7. 심볼형

Loading comments from Disqus ...