Optional Chaining(?.
)은 ES2020에서 등장한 새로운 연산자이다.
각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있다.
옵셔널 체이닝은 예외처리에 매우 편하게 해준다.
아래의 예를 살펴보자
const person = {};
console.log(person.name.lastName); // TypeError
위에서 TypeError
가 생기는 이유는 person.name
이 undefined
인데, undefined.lastName
는 존재할 수가 없으니 TypeError
가 발생하는 것이다.
옵셔널 체이닝을 사용하지 않고는 다음과 같이 예외처리를 해주어야 한다.
const person = {};
console.log(person && person.name && person.name.lastName); // undefined
위의 예제에서 에러가 발생하지 않는 이유는 and 연산자 &&
는 첫 번째 falsy
한 값을 반환하기 떄문에 person.name
이 undefined
이기 때문에 undefined
를 반환하는 것이다.
하지만 위의 방법을 사용하면 한 단계식 깊어질 때 마다. 코드가 엄청나게 길어진다.
옵셔널 체이닝 연산자 (?.
)는 다음 단계로 가기전에 이전 단계가 null
또는 undefined
가 아니라는 것을 암묵적으로 확인한다.
const person = {};
console.log(person?.name?.lastName); // undefined
위와같이 코드를 작성하면
1. person이 null
또는 undefined
가 아니므로 다음단계로 이동한다.
2. person.name은 undefined
이므로 undefined
를 만환한다.
?.
는 연산자가 아니라, 함수나 대괄호와도 함께 동작하는 특별한 문법 구조체(syntax construct)이다.
const person1 = {
sayName(){
alert("My name is chan.");
}
};
const person2 = {};
person1.sayName?.(); // My name is chan.
person2.sayName?.(); // 아무일도 일어나지 않는다.
대괄호 []
를 사용해 객체 프로퍼티에 접글할때는 ?.[]
를 사용할 수 있다.
const person1 = {
personName: "chan"
};
const person2 = null;
const name = "personName"
console.log(person1?.[name]); // chan
console.log(person2?.[name]); // undefined
console.log(perons1?.[name]?.firstName?.firstLetter); // undefined;
?
은 delete
와 조합해 사용할 수도 있다.
delete person1?.personName; // person1이 존재하면, personName 프로퍼티가 삭제된다.
?.
은 읽기나 삭제하기는 할 수 있지만 쓰기에 사용할 수 없다.
그 이유는 ?.
은 할당 연산자의 왼쪽에서 사용할 수 없기 때문이다.
person1?.personName = "chan";
위와 같이 코드를 작성할 경우 undefined = "chan"
이 되기 때문이다.