만자의 개발일지

[JavaScript] 옵셔널 체이닝 본문

JavaScript

[JavaScript] 옵셔널 체이닝

박만자 2022. 4. 20. 15:34

옵셔널 체이닝(Optional Chaining)

자바스크립트에서 존재하지 않는 요소에 접근하려 할 때 에러가 발생할 수 있습니다. 

그래서 옵셔널 체이닝이 등장하기 전에는 AND 연산자의 단축평가를 이용해 이를 해결할 수 있었습니다.

let users = {}

console.log(users && users.user && users.user.name)
undefined

하지만 이 경우에 체이닝이 길어지면 길어질수록 코드의 복잡성이 증가한다는 단점이 있습니다.

그래서 이를 해결하기 위해 ES2020 부터 옵셔널 체이닝이 추가되었습니다.

 

옵셔널 체이닝(?.)체이닝(.)과 동일한 기능을 하는데 차이점은 옵셔널 체이닝은 nullish(null or undefined) 값을 할당하고 있는 경우에 에러를 반환하지 않고 undefined를 반환합니다.

 

옵셔널 체이닝 사용 이유

예시를 통해 살펴보도록 하겠습니다.

 

users에서 user 프로퍼티에 접근하였고 users에는 user 프로퍼티가 존재하지 않기 때문에 undefined가 할당됩니다.

그 다음 undefined가 할당된 users.user에서 name 프로퍼티에 접근하였고 당연히 다음과 같이 에러가 발생합니다.

let users = {}

console.log(users.user.name)
TypeError: Cannot read property 'name' of undefined

하지만 위 경우에서 옵셔널 체이닝을 사용하면 에러가 발생하지 않고 undefined가 출력됩니다.

옵셔널 체이닝이 참조값이 nullish 한지 판단한 후 nullish 하다면 에러가 아닌 undefined를 반환하기 때문입니다.

따라서 값이 누락될 가능성이 있는 경우에 옵셔널 체이닝을 사용하면 프로그램의 안정성을 높일 수 있고 보다 간단하게 표현할 수 있습니다.

let users = {}

console.log(users.user?.name)
undefined

 

옵셔널 체이닝의 단축 평가

다음 예시를 보도록하겠습니다.

 

usersnull로 할당되어있고 옵셔널 체이닝을 통해 user 프로퍼티에 안전하게 접근하였습니다.

두 번째 console.log를 보면 users.userundefined가 할당되어있는 상태에서 체이닝을 통해 name 프로퍼티에 접근하였는데 어떻게 옵셔널 체이닝 없이 undefined가 반환되는 것일까요?

let users = null

console.log(users?.user)
console.log(users?.user.name)
undefined
undefined

옵셔널 체이닝(?.)은 바로 앞에있는 평가 대상에만 적용되고 확장되지 않습니다. 여기서는 users 가 평가대상이 됩니다.

옵셔널 체이닝은 평가 대상이 nullish 한 경우 즉시 평가를 멈추게됩니다. 이를 옵셔널 체이닝의 단축 평가(short-circuit)라고 합니다.

이러한 이유 때문에 name 프로퍼티까지 평가하지 않고 중간에 평가를 멈춘 후 undefined를 반환하여 에러가 발생하지 않는 것입니다.

 

 

옵셔널 체이닝 사용법

옵셔널 체이닝은 다양한 방법으로 사용할 수 있습니다.

null/undefined 체크

옵셔널 체이닝의 기본적인 사용법으로 참조값이 nullish 한지 체크할 때 사용합니다.

let users = {}

console.log(users.user?.name)
undefined

함수의 호출

존재하지 않을 수 있는 함수를 호출할 때 옵셔널 체이닝을 사용함으로써 예외를 발생시키는 것 대신에 자동으로 undefined를 반환합니다.

let users = {}

console.log(users.func?.())
undefined

대괄호 표현식(Bracket notation)

프로퍼티에 대괄호 표현식을 사용해서 접근할 때 옵셔널 체이닝을 사용하여 안전하게 접근할 수 있습니다.

let users = null

console.log(users?.['user'])
undefined

 

배열 요소에 접근할 때에도 대괄호를 사용하기 때문에 역시 옵셔널 체이닝을 사용할 수 있습니다.

let arr = [1, 2, 3, 4, 5]

console.log(arr?.[5])
undefined

null 병합 연산자와 같이 사용하기

옵셔널 체이닝을 사용한 후 undefined가 반환되었을 때 null 병합 연산자(??)를 사용해 기본 값을 할당할 수 있습니다.

let user = {
    age: 19
}

user.name = user?.name ?? '홍길동'

console.log(user.name)
홍길동

 

옵셔널 체이닝 사용시 주의점

옵셔널 체이닝을 사용할 때 몇 가지 주의점이 있습니다.

옵셔널 체이닝은 구식 브라우저에서 지원하지 않는다.

옵셔널 체이닝은 생긴지 얼마 안 된 문법입니다. 때문에 구식 브라우저에서는 폴리필(Polyfill)을 필요로 합니다.

폴리필은 브라우저가 지원하지 않는 자바스크립트 코드를 지원 가능하도록 변환한 코드를 의미합니다.
쉽게 말해 최신 자바스크립트의 기능을 구식 자바스크립트 코드로 똑같이 구현한 코드를 의미합니다.

옵셔널 체이닝은 꼭 필요한 경우에만 사용해야 한다.

옵셔널 체이닝은 존재하지 않아도 괜찮은 대상에만 사용해야 합니다.

논리상으로 필수적으로 존재해야하는 값에 옵셔널 체이닝을 사용하게되면 실수로 값을 할당하지 않았을 경우 에러를 발견하지 못하고 디버깅이 어려워 질 수 있습니다.

옵셔널 체이닝 앞의 변수는 꼭 선언되있어야 한다.

옵셔널 체이닝은 선언이 완료된 변수를 대상으로만 동작하기 때문에 옵셔널 체이닝을 사용하려면 let, const, var를 통해 변수를 선언해야만 합니다. 

console.log(user?.name)
ReferenceError: user is not defined

위 예시에서 변수 user가 선언되어있지 않기 때문에 옵셔널 체이닝user를 평가할 수 없습니다.

옵셔널 체이닝은 값을 할당할 때 사용할 수 없다.

옵셔널 체이닝은 값을 읽고 삭제할때에는 사용할 수 있지만 쓰기에는 사용할 수 없습니다.

이유는 다음과 같습니다.

let user = undefined

user?.name = '홍길동' // undefined = '홍길동'
SyntaxError: Invalid left-hand side in assignment

위 예시에서 userundefined가 할당되어있고 옵셔널 체이닝을 통해 name 프로퍼티에 값을 할당하려 합니다.

하지만 user의 값이 nullish하기 때문에 옵셔널 체이닝undefined를 반환하게 되고 때문에 undefined = '홍길동' 이 되어버리기 떄문에 위와 같이 에러가 발생하는 것입니다.

 

위에서 설명한 논리 연산자의 단축평가null 병합 연산자가 궁금하신 분은 아래 글을 참고하시면 도움이 됩니다.

https://yoo11052.tistory.com/166

 

[JavaScript] 논리 연산자(&&, ||)를 사용한 단축 평가

OR 연산자가 둘중 하나의 조건만 참일 경우 참을 반환한다는것도 알고, AND 연산자는 두 조건 모두 참일 경우 참을 반환한다는 것도 아는데, 이게 왜 이렇게 동작하는지에 대해 고민한적이 없었습

yoo11052.tistory.com

https://yoo11052.tistory.com/167?category=946829 

 

[JavaScript] null 병합 연산자

null 병합 연산자(Nullish Coalescing Operator) null 병합 연산자(??)는 왼쪽 값이 null 혹은 undefined 인경우 오른쪽 값을 반환하는 연산자입니다. 언뜻 보면 OR 연산자의 단축 평가와 매우 유사하지만 두 연산

yoo11052.tistory.com

 

참고

 

 

Comments