※ 지난번 Node.js v14 발표에 대한 글 작성시 주요 특징들로 언급되었던 Optional Chaining / Nullish / Intl.DIsplayNames /
Intl.DateTimeFormat 에 대해 알아보겠습니다.
Optional chaining
MDN docs 에 나와있는 옵셔널 체이닝에 대한 설명입니다.
- 옵셔널 체이닝 연산자인 ?. 는 체인의 각 참조가 유효한지 명시적으로 검증할 필요 없이 연결된 객체의 체인 내에 있는 속성 값을 읽을 수 있도록 합니다. ?. 연산자 함수는 . 체이닝 연산자와 유사하지만, 참조가 nullish (null 혹은 undefined) 일때 에러를 발생시키는 대신 표현식은 undefined 값을 반환합니다. 또한 함수 호출과 함께 사용할 때, 지정한 함수가 존재하지 않는다면 undefined 를 반환합니다. 이로 인해 참조가 누락될 수 있는 가능성이 있는 경우 체인 속성에 접근할 때 더 짧고 간단한 표현식을 만들어냅니다. 또한 어떤 속성이 필요한지에 대한 보장이 없는 경우 객체의 내용을 탐색하는데 도움이 됩니다.
예시를 보겠습니다.
/* v12 */
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const dogName = adventurer.dog.name;
console.log(dogName);
// TypeError: Cannot read property 'name' of undefined
console.log(adventurer.someNonExistentMethod());
// TypeError: adventurer.someNonExistentMethod is not a function
/* v14 */
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined
console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined
위처럼 v12 와 v14 에서 명확히 차이점을 볼 수 있습니다. adventurer 객체엔 name 과 cat 프로퍼티가 있고 name 은 'Alice' , cat 은
{ name : 'Dinah' } 라는 객체를 갖고 있습니다. v12 의 경우 adventurer 에 존재하지 않는 dog 프로퍼티의 name 에 접근시 타입에러가 발생합니다. someNonExistentMethod 또한 존재하지 않기에 호출시 마찬가지로 타입에러가 발생합니다.
v14 에서도 객체의 프로퍼티 접근에 . 연산자를 사용했다면 같은 에러가 발생하겠지만, ?. 연산자를 사용함으로써 이러한 에러 없이 객체 프로퍼티에 접근할 수 있습니다. 위와 동일한 호출에서 v14 의 ?. 연산자를 통해 undefined 로 반환받는 부분을 확인할 수 있습니다.
Nullish coalescing operator
MDN docs 에 나와있는 설명입니다.
- null 병합 연산자 ( ?? ) 는 왼쪽 피연산자가 null 이거나 undefined 일 때는 오른쪽 피연산자를 반환하고, 그 외의 경우엔 왼쪽 피연산자를 반환하는 논리 연산자입니다. OR 논리 연산자 ( || ) 와 반대로, 왼쪽 피연산자가 null 혹은 undefined 가 아닌 허위의 값이면 그 값이 반환됩니다. 다시말해, || 를 사용하여 foo 변수에 디폴트 값을 할당할 때 잘못된 값을 사용 가능한것 (eg. '' 또는 0) 으로 간주하여 기대치않은 동작이 발생할 수 있습니다.
예시를 보겠습니다.
const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"
const topaz = null || 'default string';
console.log(topaz);
// expected output: "default string"
const baz = 0 ?? 42;
console.log(baz);
// expected output: 0
const pearl = 0 || 42;
console.log(pearl);
// expected output: 42
변수 foo 와 topaz 의 경우, 왼쪽 피연산자가 null 이기에 ?? 연산자나 || 연산자 어느것을 사용하더라도 논리적 결과에 따라 오른쪽 피연산자가 반환됩니다. 하지만 baz 와 pearl 변수 할당시 왼쪽 피연산자가 0 (null 혹은 undefined 가 아닌 허위의 값) 이므로 ?? 연산자를 사용했을 때는 0 이 반환되지만, || 사용시 42 가 반환되는 차이점이 있습니다. 설명에는 null 혹은 undefined 가 아닌 허위의 값을 falsy value 라고 하는데, 위의 예시처럼 0 외에도 '' , false 와 같은 값이 있습니다.
const gold = { description: '' };
const gold_description = gold.description || 'non existence';
console.log(gold_description);
// output : 'non existence'
const new_gold_description = gold.description ?? 'non existence';
// output : ''
억지로 예시를 만들어보자면, gold 라는 변수에 description 프로퍼티를 가진 객체를 할당하고 gold_description 변수에 || 연산자를 사용해서 gold 객체에 description 프로퍼티가 존재하지 않는 경우 'non existence' 를 기본값으로 세팅하려는 의도를 갖고 위와같이 작성했습니다. 하지만 위의 경우 gold 의 description 값이 '' 로 분명히 존재하지만, '' 는 falsy value 이므로 || 연산자를 거쳐 우측 피연산자인 'non existence' 값이 gold_description 변수에 할당됩니다. 이러한 경우 ?? 연산자를 사용해 기존 의도대로 코드를 작성할 수 있습니다.
Intl.DisplayNames
MDN docs 에 나와있는 설명입니다.
- Intl.DisplayNames 객체는 언어, 지역 및 스크립트 표시 이름을 일관되게 번역 가능하게 하는 객체의 생성자입니다.
간단히 예시를 보겠습니다.
// Get display names of region in English
var regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
console.log(regionNames.of('419')); // "Latin America"
console.log(regionNames.of('BZ')); // "Belize"
console.log(regionNames.of('US')); // "United States"
console.log(regionNames.of('BA')); // "Bosnia & Herzegovina"
console.log(regionNames.of('MM')); // "Myanmar (Burma)"
// Get display names of region in Traditional Chinese
regionNames = new Intl.DisplayNames(['zh-Hant'], {type: 'region'});
console.log(regionNames.of('419')); // "拉丁美洲"
console.log(regionNames.of('BZ')); // "貝里斯"
console.log(regionNames.of('US')); // "美國"
console.log(regionNames.of('BA')); // "波士尼亞與赫塞哥維納"
console.log(regionNames.of('MM')); // "緬甸"
Intl.DisplayNames 생성자를 통한 객체 생성시 지역을 지정하면, 위처럼 지역 코드에 대한 표시 이름을 지정한 지역 언어로 가져올 수 있습니다. (en : 영어, zh-Hant : 중국어)
Intl.DisplayNames 에 대한 더 많은 정보
Intl.DateTimeFormat
MDN docs 에 나와있는 설명입니다.
- Intl.DateTimeFormat 객체는 언어에 따라 날짜 및 시간 형식을 사용 가능하게 하는 객체의 생성자입니다.
간단히 예시를 보겠습니다.
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
// Results below assume UTC timezone - your results may vary
console.log(new Intl.DateTimeFormat('en-US').format(date));
// expected output: "12/20/2012"
console.log(new Intl.DateTimeFormat('en-GB').format(date));
// expected output: "20/12/2012"
console.log(new Intl.DateTimeFormat('ko-KR').format(date));
// expected output: "2012. 12. 20."
// Include a fallback language, in this case Indonesian
console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date));
// expected output: "20/12/2012"
선언된 date 변수를 생성자 Intl.DateTimeFormat 에 의해 만들어진 객체를 사용해 포맷을 출력해보면, 객체 생성시 사용된 지역에서 사용되는 날짜 형식에 따라 출력 결과가 변하는 것을 볼 수 있습니다. en-US (미국) : 월-일-년 / en-GB (영국) : 일-월-년 / 한국 : 년-월-일 순서입니다. 마지막 예시처럼 생성자의 매개 변수에 배열이 사용된 경우는 대체 언어를 지정한 경우이며 ban (발리어) 가 지원되지 않기 때문에 id (인도네시아) 로 대체되어 해당 포맷에 맞게 출력되었습니다.
'Backend > Node.js' 카테고리의 다른 글
[Node.js] Date 라이브러리 비교 (0) | 2021.02.27 |
---|---|
[Node.js] Http 라이브러리 비교 (3) | 2020.06.08 |
Medium 번역 - Node.js version 14 available now (0) | 2020.04.26 |
Node.js LTS schedule 정리 (0) | 2020.02.25 |
' nvm ls ' 출력에 대한 정리 (0) | 2020.02.16 |