고급 객체 조작
1. 널리시 연산자
널리시 연산자(Nullish)는 왼쪽 피연산자가 null
또는 undefined
일 때만 오른쪽 피연산자를 반환합니다. 이 연산자는 ES2020에 도입되었습니다. 널리시 연산자는 ??
로 표현됩니다. 논리합(OR) 연산자(||
)와 비슷하지만, null
과 undefined
만을 체크합니다. 즉, 0
, NaN
, ''
(빈 문자열) 등은 체크하지 않습니다.
const a = null;
const b = 5;
const c = a ?? b; // c는 5
const a = null;
const b = 5;
const c = a ?? b; // c는 5
널리시 연산자는 주로 기본값을 설정할 때 유용합니다. 예를 들어, 사용자가 입력한 값이 null
또는 undefined
일 때만 기본값을 사용하고 싶을 때 사용할 수 있습니다. OR 연산자와 달리 0
, NaN
, ''
(빈 문자열) 등도 유효한 값으로 간주합니다.
const name = prompt('이름을 입력하세요:') ?? '사용자';
console.log(name);
const name = prompt('이름을 입력하세요:') ?? '사용자';
console.log(name);
널리시 연산자와 논리 연산자
널리시 연산자와 논리 연산자는 함께 사용할 때는 괄호를 이용하여 우선순위를 명시해야 합니다. 괄호를 생략하면 오류가 발생합니다.
const a = 0;
const b = null;
const result = (a && b) ?? 'hello';
console.log(result);
const result2 = a && (b ?? 'hello');
console.log(result2);
const a = 0;
const b = null;
const result = (a && b) ?? 'hello';
console.log(result);
const result2 = a && (b ?? 'hello');
console.log(result2);
2. 옵셔널 체이닝
옵셔널 체이닝은 ES2020에 도입된 연산자로, 객체의 속성에 접근할 때, 해당 속성이 존재하지 않을 경우 에러를 발생시키지 않고 undefined를 반환합니다. 이를 통해 깊은 중첩 구조의 객체에서 안전하게 속성에 접근할 수 있습니다. 참조가 null
이거나 undefined
인 경우에도 에러를 발생시키지 않고, 대신 undefined
를 반환합니다.
const obj = {
a: {
b: {
c: 1,
},
},
};
console.log(obj.a?.b?.c); // 1
console.log(obj.a?.b?.d); // undefined
console.log(obj.a?.b?.c?.d); // undefined
const obj = {
a: {
b: {
c: 1,
},
},
};
console.log(obj.a?.b?.c); // 1
console.log(obj.a?.b?.d); // undefined
console.log(obj.a?.b?.c?.d); // undefined
옵셔널 체이닝이 없으면 다음과 같이 존재하지 않는 속성에 접근할 때 오류가 발생합니다.
const user = {
name: '라이캣',
address: {
city: '제주도',
stree: '고산로',
number: 58,
},
};
const zipCode = user.address.zipCode; // undefined
const company = user.company.name; // TypeError: Cannot read property 'name' of undefined
const user = {
name: '라이캣',
address: {
city: '제주도',
stree: '고산로',
number: 58,
},
};
const zipCode = user.address.zipCode; // undefined
const company = user.company.name; // TypeError: Cannot read property 'name' of undefined
기존에는 if
문을 사용하여 안전하게 접근해야 했습니다.
if (user && user.address && user.address.zipCode) {
console.log(user.address.zipCode);
} else {
console.log('zipCode가 존재하지 않습니다.');
}
if (user && user.address && user.address.zipCode) {
console.log(user.address.zipCode);
} else {
console.log('zipCode가 존재하지 않습니다.');
}
널리시 연산을 함께 사용하면 더 간결하게 작성할 수 있습니다.
cont zipCode = user?.address?.zipCode || 'zipCode가 존재하지 않습니다.';
console.log(zipCode); // zipCode가 존재하지 않습니다.
cont zipCode = user?.address?.zipCode || 'zipCode가 존재하지 않습니다.';
console.log(zipCode); // zipCode가 존재하지 않습니다.