목차
지난 게시물 nullish 연산자에 이어 옵셔널 체이닝 연산자에 대해 알아보겠습니다.
옵셔널 체이닝(optinal chaining)연산자 개념
optional chaning연산자 (?.)는 객체 내의 key에 접근할 때 그 참조가 유효한지 아닌지 직접 명시하지 않고도 접근할 수 있는 연산자입니다.
?. 앞의 평가대상이 만약 nullish ( undefined 또는 null ) 일 경우 평가를 멈추고 undefined를 반환합니다.
우리는 코드를 짜면서 객체내의 값을 접근하는 경우가 종종 있습니다. 하지만 항상 그 key값이 존재하는 경우 보다는 없는 경우도 있습니다.
예를 들어, 학생들의 점수 데이터를 가진 객체가 있습니다. mark라는 학생과 john이라는 학생의 영어점수를 접근하려고 합니다. 그런데 john은 시험을 안봐서 점수가 없습니다.
const students = {
mark: {
age: 20,
score: {
korean: 90,
english: 80,
math: 40
}
},
john: {
age: 20,
}
}
console.log(students.mark.score.english); // 80;
console.log(students.john.score.english); // TypeError: Cannot read properties of undefined (reading 'english')
이런 경우에 옵셔널 체이닝 연산자의 존재를 몰랐다면 아래와 같이 코딩을 할 수 있습니다.
console.log(students.john.score && students.john.score.english);
이렇게하면 score라는 key값에 접근이 가능할 때만 english값을 불러오려고 할 것이기 때문에 에러가 나지 않고 undefined만 반환하게 됩니다. 그럼 만약에 학생 정보에 john이라는 이름이 없어도 작동하게 하려면 어떻게 해야할까요?
console.log(students.john && students.john.score && students.john.score.english);
점점 검사할 항목이 많아진다면 코드의 길이는 길어지고 해석하기 힘들 것 같습니다. 그 불편함 속에서 생겨난 것이 옵셔널 체이닝 연산자입니다. 옵셔널 체이닝을 이용해서 이 긴 코드를 아래와 같이 바꿀 수 있습니다.
console.log(students.john?.score?.english);
?. 연산자의 왼쪽에 있는 것을 평가한뒤 undefined 또는 null이 맞다면 undefined를 반환하고 평가가 끝납니다. 만약 아니라면 계속해서 평가가 이루어지게 됩니다. 이것만으로도 엄청 편리한 연산자라는 것을 알 수 있습니다.
옵셔널 체이닝 장점
1. if문을 줄여줍니다.
서버에서 보내주는 객체의 형태가 아래와 같이 생겼다고 가정합니다.
user: {
name: ‘coding’,
age: 20
friends: {
‘bob’: {
name: ‘bob’,
age: 20
},
‘mark’: {
name: ‘mark’,
age: 20
}
}
}
그러면 우리는 bob이라는 친구의 나이 값을 접근하려면 const age = user.friends.bob.age;
이런 식으로 접근을 해야했습니다. 그런데 에러가 날 수 있으니 함수를 통해서 검사를 한 뒤 값을 받아오겠습니다.
function getFriendAge(user){ // user객체를 받아서 age 리턴
if(user === undefined) return undefined;
if(user.friends === undefined) return undefined;
if(user.friends.bob === undefined) return undefined;
return user.friends.bob.age;
}
const age = getFriendAge(user);
에러를 막기 위해서 if문을 통해서 검사를 계속해서 하다보니 이 함수의 목적은 값을 return하는 것인데 함수의 목적이 바로바로 보이지 않게 되었습니다. 이것을 옵셔널 체이닝을 이용한다면 어떻게 될까요?
function getFriendAge(user) {
return user?.friends?.bob?.age;
}
이렇게 하면 함수가 무엇을 의미하는지 바로바로 볼 수 있어서 편하지 않나요?
2. nullish연산자와 함께 쓰면 기본값 주기에 용이합니다.
const user = {};
const userAddress = user.info?.address ?? '모르는 주소'; // '모르는 주소'
3. 대괄호 표기법에도 옵셔널 체이닝이 가능합니다.
객체내의 값에 접근하는 방법에는 두가지가 있습니다. 여태까지 접근하면 (.) 연산자 대신 대괄호 표기법을 통해서 접근할 수 있습니다.
const user = {
info: {
firstName: 'hello world'
}
};
const key = "firstName";
const userName = user.info?.[key];
4. 존재하지 않을 수 있는 메서드를 호출할 때도 유용합니다.
const some = {
customMethod: function() {
console.log('hello optional');
}
}
let result = some.customMethod?.();
위의 코드에서 customMethod가 참조할 수 없으면 undefined를 반환하고 끝이납니다. 그러면 만약 customMethod가 메서드가 아니라 그냥 값을 가지고 있는 것이라면 어떻게 될까요?
const some = {
customMethod: 'hello?'
}
let result = some.customMethod?.();
// TypeError: some.customMethod is not a function
그러면 함수가 아니라는 타입에러가 뜨게됩니다.
5.배열에도 사용 가능합니다.
console.log(arr?.[42]); // undefined
console.log(arr[42]); // TypeError: Cannot read properties of undefined (reading '42')
주의할점
1. 존재하지 않아도 괜찮은 대상에만 적용해야합니다. 에러를 피하기 위해서 남용하다가 디버깅이 어려워질 수 있습니다.
만약 사용자 객체는 꼭 있어야하는데 그 안에 info 의 age는 꼭 필수가 아니라면 아래와 같이 코딩을 해주어야 합니다.
console.log(user?.info?.age) // 이렇게하면 user 객체가 꼭 있어야할 필요가 없다는 뜻입니다.
console.log(user.info?.age); // 이렇게하면 user 객체가 없다면 에러를 뱉을 것입니다.
2. ?.(optional chaining)앞에 오는 변수는 선언이 되어 있어야합니다.
선언되지 않은 변수에는 옵셔널 체이닝 연산자를 사용하더라도 에러가 뜰 것입니다.
'자바스크립트' 카테고리의 다른 글
react-query v3 에서 v4 (tanstack/react-query)로 올릴 때 꼭 주의해야할 사항! (+ 해결방안) (0) | 2023.01.02 |
---|---|
모듈에 대한 설명 (import, export, require, module.export 등등) (0) | 2022.05.08 |
자바스크립트 문자열 앞 뒤에 원하는 길이만큼 문자 추가하기(padEnd, padStart) (0) | 2022.04.24 |
자바스크립트 nullish 연산자 (OR 연산자와 차이점) (0) | 2022.04.16 |