타닥타닥 개발자의 일상

JavaScript / Optional Chaining을 이용해서 코드 훨씬 간결하게 작성하기 + nullish coalescing operator 이용해서 optional chaining 기능 극대화 / '.?' 만 찍으면 끝 본문

코딩 기록/JavaScript

JavaScript / Optional Chaining을 이용해서 코드 훨씬 간결하게 작성하기 + nullish coalescing operator 이용해서 optional chaining 기능 극대화 / '.?' 만 찍으면 끝

NomadHaven 2023. 5. 18. 23:41

 

아래와 같은 코드가 있다고 하자.

아래의 코드에서 object restaurant는 자신의 object 외부에있는 또다른 object인 openingHour를 불러와서 key와 value를 구성하고 있다.

'use strict';

const weekdays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];

const openingHours = {
  [weekdays[3]]: {
    open: 12,
    close: 22,
  },
  [weekdays[4]]: {
    open: 11,
    close: 23,
  },
  [weekdays[5]]: {
    open: 0, // Open 24 hours
    close: 24,
  },
};


const restaurant = {
  name: 'Classico Italiano',
  location: 'Via Angelo Tavanti 23, Firenze, Italy',
  categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
  starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
  mainMenu: ['Pizza', 'Pasta', 'Risotto'],

  //ES6 enhanced object literals
  openingHours,

  order(starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

  orderDeliver({ starterIndex = 1, mainIndex = 0, time = '20:00', address }) {
    console.log(
      `Order Received! ${this.starterMenu[starterIndex]} and ${this.mainMenu[mainIndex]} will be deliverd to ${address} at ${time}`
    );
  },

  orderPasta(ing1, ing2, ing3) {
    console.log(
      `Here is your delicious pasta with ${ing1}, ${ing2} and ${ing3}`
    );
  },

  orderPizza(mainIngredient, ...otherIngredients) {
    console.log(mainIngredient);
    console.log(otherIngredients);
  },
};

 

만약 외부에서 해당 레스토랑의 월요일(mon) open 시간을 요청한다고 하자.

그렇다면 외부의 요청시간에 답하기 위해서 restaurant 의 openingHour key 값에 있는 월요일(mon) 시간의 value 을 보내야 겠지만,

 

restaurant object가 사용하는 외부의 openingHour object 내부에는 월요일(mon)의 key 값과 value 값이 없다.

 

따라서 막무가내로 아래처럼 출력하면 

console.log(restaurant.openingHours.mon.open);

이런 오류가 난다.

 

우선 오류를 피하는게 가장 급한일이라 생각하고, 바쁜대로 undefined 값이라도 보내야 된다고 하자.

if문을 사용해서 아래와 같이 작성할수도 있겠지만,

//restaurant의 open 시간이 있고 open 시간 중 월요일(mon)이 있으면 해당 시간을 출력
if (restaurant.openingHours && restaurant.openingHours.mon) console.log(restaurant.openingHours.mon.open);

 

Optional Chaining을 이용하면 코드가 훨씬 간단해 진다. 그저 value를 얻고자 하는 속성에 "?"만 붙여주면 된다.

console.log(restaurant.openingHours?.mon?.open);

 

 

이제 외부에서 restaurant의 토요일 오픈 시간을 요청한다고 가정해보자.

다행히 openingHours object에서 토요일 값이 설정되어 있어서 요청을 보낼수 있겠다 싶었는데,

const days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];

for (const day of days) {
console.log(day);
const open = restaurant.openingHours[day]?.open || 'closed';
console.log(`On ${day}, we open at ${open}`);
}

토요일(sat)의 openinghour이 0시 이고 이 0값은 falsy value라 인식된다.

그래서 거짓으로 인식된 0시의 값 때문에 closed가 출력되고,

On sat, we open at closed라는 예상치 못한 값이 출력되고 만다.

 

이를 해결하기 위해 nullish coalescing operator를 사용한다. ||대신 ??를 사용하면 된다.

 

nullish coalescing operator 은 변수가 null 또는 undefined일 때 기본값을 지정하는 데 사용된다.

이 연산자는 변수가 null 또는 undefined인지 확인하고, 그렇다면 지정된 기본값을 반환한다.

그렇지 않으면 변수의 값을 그대로 반환합니다.

 

이 nuliish coalescing operator의 중요한 특징은 변수가 null 또는 undefined인 경우에만 기본값을 반환하며, 다른 falsy 값인 0, 빈 문자열, false 등은 기본값으로 간주하지 않는다. 따라서 openingHours의 토요일 오픈 시간인 0이 나와도, 0은 기본 값으로 간주되지 않아서 closed가 출력 되지 않는다. 

for (const day of days) {
  console.log(day);
  const open = restaurant.openingHours[day]?.open ?? 'closed';
  console.log(`On ${day}, we open at ${open}`);
}

덕분에 토요일에도 0시에 오픈한다는 값이 잘 출력된다.

 

nullish coalescing operator는 다양하게 이용된다.

 

method의 유무를 확인 할때도 이용되는데, 아래는 그 예시다

console.log(restaurant.order?.(0, 1) ?? 'Method does not exist');
//order는 존재하는 method 이므로 ['Focaccia', 'Pasta'] 가 출력된다.
console.log(restaurant.orderRisotto?.(0, 1) ?? 'Method does not exist'); 
//orderRisotto는 존재하지 않는 method 이므로 undefined이 되고, 그로인해 기본값 
//Method does not exist 가 출력된다.

 

배열에 값이 있는지 확인할때도 사용할수 있다.

 

1.배열에 값이 있을때

const users = [
  { name: 'Nomad', email: 'hello@nomad.io' },
  { name: 'aboc', email: 'aboc@nomad.io' },
 ];


console.log(users[0]?.name ?? 'User array empty'); //Nomad가 출력된다
console.log(users[1]?.name ?? 'User array empty'); //aboc가 출력된다.

 

2. 배열에 값이 없을때

const users = [];

console.log(users[0]?.name ?? 'User array empty'); 
//user[0].name은 undefine 값이므로 User array empty가 출력.

console.log(users[1]?.name ?? 'User array empty');
//user[1].name은 undefine 값이므로 User array empty가 출력.

 

만약 nullish coalescing operator를 쓰지 않고 if else문을 써서 배열에 값이 있는지 확인하고, 없을 경우 기본값을 출력하도록 설정한다면

if (users.length > 0) console.log(users[0].name);
else console.log('User array empty');

이처럼 코드가 몹시 길어졌을 것이다. 

 

 nullish coalescing operator를 이용해서 깔끔한 코드를 작성해보자.

Comments