Skip to content
Dev-blog

ES6 이후의 변경점 총정리

js5 min read

너무 오랜만의 포스팅입니다. 그 동안 방치했던 것을 반성하면서 새로운 글을 써야 하겠지만... 일단 회사 블로그에 올렸던 글을 여기에도 가져옵니다. 이제 다시 블로그를 좀 신경써보려고 합니다.


2009년에 ES5가 등장하고 2015년에 ES6가 등장하며 큰 변화를 겪은 이후, ECMA는 매년 새로운 자바스크립트 표준을 발표합니다. ES6 이후 추가된 내용중 일부는 이미 사용하고 있지만, 자세히 알아본 적이 없는 것 같아서 정리하는 시간을 가져봤습니다. ECMAScript에 대한 자세한 설명은 생략하고, ES6(ES2015) 이후에 어떤 것들이 추가되었는지 나열해 보려고 합니다.

ES2016

ES2016에서는 두 가지 기능이 새롭게 도입되었습니다.

  • Array.prototype.includes()
  • 지수 연산자(**)

ES2016-1. Array.prototype.includes()

includes() 메서드는 배열에 특정 원소가 포함되어 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.

1const numbers = [1, 2, 4, 8];
2numbers.includes(2);
3//true
4numbers.includes(3);
5//false

includes()에 두 번째 값으로 인덱스를 추가해서 원소를 검색할 수 있습니다. 기본값은 0이지만 음수를 전달할 수도 있습니다. MDN - includes

ES2016-2. 지수 연산자

1//ES2016 이전의 지수 계산
2Math.pow(2, 2); // 4
3Math.pow(2, 3); // 8
4
5// 지수 연산자 **를 사용
62**2; // 4
72**3; // 8

ES2017

ES2017에서는 익히 잘 알고 계시는 async, await 등 많은 기능이 추가되었습니다. async를 제외한 나머지 기능을 알아보겠습니다.

ES2017-1. 문자열 패딩

문자열 끝 부분이나 시작 부분을 다른 문자열로 채워 주어진 길이를 만족하는 새로운 문자열을 만들어낼 수 있습니다. String.prototype.padStart(), String.prototype.padEnd()로 사용할 수 있습니다.

1"hello".padStart(6); " hello"
2"hello".padEnd(6); "hello "
3"hello".padStart(3); "hello" // 문자열 길이보다 목표 문자열 길이가 짧다면 채워넣지 않고 그대로 반환
4
5// 사용자가 지정한 값으로 채우는 것도 가능합니다.
6"hello".padEnd(20, "*");
7// "hello***************"

MDN - padStart MDN - padEnd

ES2017-2. Object.entries()와 Object.values()

객체 내부의 값에 접근하는 방법입니다.

1const ppap = {
2 pplead: 'Ten Kim',
3 aplead: 'GJ Han',
4 pp: ['Widget Lee'],
5 ap: ['Someone Min']
6}
7
8Object.entries(ppap); // 객체의 키와 값을 포함하는 배열의 배열을 반환
9[
10 ["pplead", "Tem Kim"],
11 ["aplead", "GJ Han"],
12 ["pp", ["Widget Lee"]],
13 ["ap", ["Someone Min"]]
14]
15
16Object.values(ppap); // 객체의 값이 담긴 배열을 반환
17[
18 "Ten Kim",
19 "GJ Han",
20 [ "Widget Lee" ],
21 [ "Someone Min" ]
22]
23
24// 이런 식으로 객체를 map으로 쉽게 바꿀 수 있음
25const obj = { foo: 'bar', baz: 42 };
26const map = new Map(Object.entries(obj));
27console.log(map); // Map { foo: "bar", baz: 42 }

MDN - Object.entries MDN - Object.values

ES2017-3. Object.getOwnPropertyDescriptors()

객체가 소유한 모든 상속받지 않은 속성 설명자를 반환합니다.

1const myObj = {
2 name: "Woongki",
3 age: '30 over',
4 get myname() {
5 return this.name;
6 }
7}
8
9Object.getOwnPropertyDescriptors(myObj);
10
11{
12 "name": {
13 "value": "Woongki",
14 "writable": true,
15 "enumerable": true,
16 "configurable": true
17 },
18 "age": {
19 "value": "30 over",
20 "writable": true,
21 "enumerable": true,
22 "configurable": true
23 },
24 "myname": {
25 "enumerable": true,
26 "configurable": true,
27 "set": undefined,
28 "get": myname() {
29 return this.name;
30 }
31 }
32}

MDN - Object.getOwnPropertyDescriptors

ES2017-4. Trailing Comma

배열 리터럴에서는 항상 trailing comma가 허용되었습니다. ES6에서 객체 리터럴에도 도입되었고, 함수에도 도입된 것이 ES2017입니다.

1function f(p) {}
2function f(p,) {}
3
4(p) => {};
5(p,) => {};

MDN - Trailing commas

ES2017-5. Atomics, SharedArrayBuffer

  • 멀티 스레드 환경을 지원하기 위한 기능들입니다. 이 부분은 저도 좀 더 심도있게 공부한 후에 더 자세히 서술할 수 있을 것 같아서 일단 간략히 설명하고 지나가겠습니다.
  • SharedArrayBuffer는 고정된 길이의 바이너리 데이터 버퍼를 표현하는데 사용되며 컨텐츠는 0으로 초기화됩니다. 메인스레드 혹은 다른 worker와의 메모리 공유를 위해 쓰일 수 있습니다.
  • 메모리가 공유되면 여러 스레드가 메모리에서 동일한 데이터를 읽고 쓸 수 있습니다. Atomics를 이용한 작업은 이러한 환경에서도 정확하게 값을 읽고 쓸 수 있게 해줍니다. 또 Atomics를 이용한 작업은 다음 작업이 시작되기 전에 완료되고, 중단되지 않는 것이 보장됩니다.
  • 허나 SharedArrayBuffer는 Spectre 에 대한 대응으로 2018년 1월 이후 거의 대부분의 브라우저에서 비활성화가 되어있다가 크롬68, 엣지79, 파이어폭스79 이후 버전의 브라우저에서만 사용이 가능합니다. MDN - SharedArrayBufferMDN - Atomics

ES2018

ES2018-1. Object rest/spread

ES6에서 배열의 spread, rest가 가능해졌고, ES2018에서는 객체에도 사용하는 것이 가능해졌습니다. 배열과 마찬가지로 객체도 쉽게 얕은 복사를 할 수 있게 되었습니다.

1const myObj = {
2 a: 1,
3 b: 3,
4 c: 'cc',
5 d: 100
6};
7
8const {a, b, ...z} = myObj;
9console.log(a); // 1
10console.log(b); // 3
11console.log(z); // { "c": "cc", "d": 100 }
12
13
14const spread = {
15 ...myObj,
16 a: 10,
17 e: 30,
18};
19
20console.log(spread);
21/**
22{
23 "a": 10,
24 "b": 3,
25 "c": "cc",
26 "d": 100,
27 "e": 30
28}
29*/

ES2018-2. Async iteration

제너레이터 함수와 for of 문에서 async를 사용할 수 있습니다.

1(async() => {
2 const promises = [1, 2, 3].map((timer) => (
3 new Promise((resolve) => {
4 setTimeout(() => resolve(timer), timer*1000);
5 })
6 ));
7
8 for await (const result of promises) {
9 console.log(result);
10 }
11})();

MDN-for...of

ES2018-3. Promise.prototype.finally()

finally() 메소드는 Promise가 처리되면 충족되거나 거부되는지의 여부에는 상관없이 무조건 콜백 함수가 실행됩니다. finally() 또한 프로미스를 반환하고, then과 catch로 계속 연결할 수 있지만, finally가 반환한 값이 아니라 그 전의 프로미스가 반환한 값을 갖게 됩니다. 프로미스의 성공 여부와 관계가 없기 때문에 finally는 아무런 인자도 받지 않습니다.

1const myPromise = new Promise((resolve, reject) => {
2 resolve();
3});
4
5myPromise.then(() =>{
6 console.log('1');
7 return 'still working at 2am'
8}).finally(res => { // 아무런 인자도 받지 않기 때문에 undefined가 나옴
9 console.log(2, res)
10 return 'finally'
11}).then(res => {
12 console.log(3, res);
13});
14
15// 1
16// 2 undefined
17// 3 still working at 2am

ES2018-4. 정규식 기능 추가

ES2018에는 네 가지 새로운 정규식 관련 기능이 추가되었습니다.

  • s(dotAll) 플래그 -> . 표현식은 개행문자를 제외한 모든 문자였으나, s플래그를 달면 개행식도 포함하게 됩니다.
1/foo.bar/s.test('foo\nbar'); // true
  • 명명된 캡쳐 그룹 -> (?<name>) 구문을 사용하여 캡쳐 그룹에 원하는 이름을 붙일 수 있습니다.
1let regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
2let result = regex.exec('2021-06-21');
3console.log(result.groups);
4{
5 "year": "2021",
6 "month": "06",
7 "day": "21"
8}
  • 룩비하인드 어서션
    • 룩비하인드 어서션을 사용하면 패턴 앞에 다른 패턴이 있는지 여부를 확인할 수 있다고 합니다.
    • 긍정 룩비하인드 어서션
1const regex = /(?<=\$)\d+(\.\d*)?/;
2const result = regex.exec('$10.53');
3[
4 "10.53",
5 ".53"
6]
7const result2 = regex.exec('&10.53');
8// null
  • 부정 룩비하인드 어서션 (?<!...)
  • 유니코드 속성 이스케이프 \p{...}(긍정), \P{...}(부정) 형식으로 유니코드 속성 이스케이프를 사용할 수 있습니다.
1const sentence = 'A ticket to 大阪 costs ¥2000 👌.';
2
3const regexpEmojiPresentation = /\p{Emoji_Presentation}/gu;
4console.log(sentence.match(regexpEmojiPresentation));
5// expected output: Array ["👌"]
6
7const regexpNonLatin = /\P{Script_Extensions=Latin}+/gu;
8console.log(sentence.match(regexpNonLatin));
9// expected output: Array [" ", " ", " 大阪 ", " ¥2000 👌."]
10
11const regexpCurrencyOrPunctuation = /\p{Sc}|\p{P}/gu;
12console.log(sentence.match(regexpCurrencyOrPunctuation));
13// expected output: Array ["¥", "."]

MDN - Unicode property escapes

ES2019

ES2019-1. Array.prototype.flat()과 Array.prototype.flatMap()

  • Array.prototype.flat() Array.prototype.flat()은 지정한 깊이까지 배열을 재귀적으로 평면화합니다. 깊이 인수가 지정되지 않으면 1이 기본값이고, Infinity로 지정하면 모든 중첩 배열을 평면화할 수 있습니다.
1const arr1 = [1, 2, [3, 4]];
2arr1.flat();
3// [1, 2, 3, 4]
4
5const arr2 = [1, 2, [3, 4, [5, 6]]];
6arr2.flat();
7// [1, 2, 3, 4, [5, 6]]
8
9const arr3 = [1, 2, [3, 4, [5, 6]]];
10arr3.flat(2);
11// [1, 2, 3, 4, 5, 6]
12
13const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
14arr4.flat(Infinity);
15// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
16
17// 배열의 빈 부분도 제거합니다
18const arr5 = [1, 2, , 4, 5];
19arr5.flat();
20// [1, 2, 4, 5]

MDN - flat Node11부터 사용 가능하고 IE는 불가합니다. (참고로 오늘 소개한 모든 기능이 IE에선 불가합니다..)

  • Array.prototype.flatMap() 메서드는 먼저 매핑함수를 사용해 각 엘리먼트에 대해 map 수행 후, 결과를 새로운 배열로 평탄화합니다. 이는 깊이 1의 flat이 뒤따르는 map과 동일하지만, flatMap 은 아주 유용하며 둘을 하나의 메소드로 병합할 때 조금 더 효율적입니다.
1let arr1 = ["it's Sunny in", "", "California"];
2
3arr1.map(x=>x.split(" "));
4// [["it's","Sunny","in"],[""],["California"]]
5
6arr1.flatMap(x => x.split(" "));
7// ["it's","Sunny","in", "", "California"]

MDN - flatMap

ES2019-2. Object.fromEntries()

Object.fromEntries는 키/값 쌍이 포함된 iterable을 객체로 변환합니다.(Map도 객체로 변환이 가능). Node12 이상 버전부터 가능합니다.

1const keyVal = [
2 ['key1', 'val1'],
3 ['key2', 'val2']
4];
5const obj = Object.fromEntries(keyVal);
6console.log(obj);
7{
8 "key1": "val1",
9 "key2": "val2"
10}

MDN - fromEntries

ES2019-3. String.prototype.trimStart()와 String.prototype.trimEnd()

trimStart는 문자열 시작 부분의 공백을 제거하고 trimEnd는 문자열 끝 부분의 공백을 제거합니다.

1const greeting = ' Hello world! ';
2
3console.log(greeting);
4// expected output: " Hello world! ";
5
6console.log(greeting.trimStart());
7// expected output: "Hello world! ";
8
9console.log(greeting.trimLeft());
10// expected output: "Hello world! ";
11
12console.log(greeting.trimEnd());
13// expected output: " Hello world!";
14
15console.log(greeting.trimRight());
16// expected output: " Hello world!";

MDN - trimStart

ES2019-4. 선택적 catch 할당

ES2019 이전에는 catch절에 항상 예외 변수를 포함해야 하지만, ES2019에서는 이를 생략할 수 있습니다.

1try {
2 ...
3} catch {
4 ...
5}

ES2019-5. Function.prototype.toString()

함수 객체의 .toString() 메서드는 함수의 소스 코드를 나타내는 문자열을 반환합니다. ES2016까지는 소스 코드에서 주석이나 공백 문자를 제거했지만, ES2019에서 개정되어 문자열에 주석 등도 포함됩니다.

1function sum(a, b) {
2 return a+b;
3 // 두 인자의 합을 리턴합니다.
4}
5
6console.log(sum.toString());
7'function sum(a, b) { return a+b; // 두 인자의 합을 리턴합니다. }'

MDN - toString

ES2019-6. Symbol.prototype.description

심벌 객체의 description은 해당 심벌 객체의 설명을 반환합니다.

1Symbol('desc').toString(); // "Symbol(desc)"
2Symbol('desc').description; // "desc"

MDN - description

ES2020

ES2020-1. BigInt

현재 정수의 최대값은 2**53-1이며 Number.MAX_SAFE_INTEGER를 통해 확인할 수 있습니다. BigInt는 정수 리터럴의 뒤에 n을 붙이거나(10n) 함수 BigInt()를 호출해 생성할 수 있습니다.

BigIntNumber는 어떤 면에서 비슷하지만 중요한 차이점이 있습니다. 예컨대 BigInt는 내장 Math객체의 메서드와 함께 사용할 수 없고, 연산에서 Number와 혼합해 사용할 수 없습니다. 따라서 먼저 같은 자료형으로 변환해야 합니다. 그러나, BigIntNumber로 바뀌면 정확성을 잃을 수 있으니 주의해야 합니다. 또한 bigDecimal이 아니기 때문에 소수점 이하는 언제나 버립니다.

1const theBiggestInt = 9007199254740991n;
2
3const bigintSum = theBiggestInt + 1n;
4// 9007199254740992n
5
6const alsoHuge = BigInt(9007199254740991);
7// 9007199254740991n
8
9typeof bigintSum
10// "bigint"

MDN - BigInt

ES2020-2. Dynamic import

ES2020부터는 필요할 때 모듈을 동적으로 가져올 수 있습니다.

1if (condition1 && condition2) {
2 const module = await import('./path/to/module.js');
3 module.doSomething();
4}

MDN - import

ES2020-3. 옵셔널 체이닝

연산자 ?. 는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있습니다. ?. 연산자는 . 체이닝 연산자와 유사하게 작동하지만, 만약 참조가 nullish(null 또는 undefined)이라면, 에러가 발생하는 것 대신에 표현식의 리턴 값은 undefined로 단락됩니다.

1const adventurer = {
2 name: 'Alice',
3 cat: {
4 name: 'Dinah'
5 }
6};
7
8const catName = adventurer.cat?.name;
9console.log(catName);
10// 'Dinah'
11
12const dogName = adventurer.dog?.name;
13console.log(dogName);
14// undefined

MDN - optional chaining (Node v14부터 사용 가능)

ES2020-4. Promise.allSettled()

allSettled는 성공 실패 여부와 무관하게 모든 프로미스들이 완료될 떄까지 기다렸다가 각각의 결과를 설명하는 객체 배열을 반환합니다.

1const promiseArr = [
2 new Promise((resolve, reject) => setTimeout(resolve, 1000, 'abc')),
3 new Promise((resolve, reject) => setTimeout(reject, 2000)),
4 new Promise((resolve, reject) => setTimeout(resolve, 3000)),
5];
6
7Promise.allSettled(promiseArr).then(data => console.log(data));
8
9[
10 {
11 "status": "fulfilled",
12 "value": "abc"
13 },
14 {
15 "status": "rejected"
16 },
17 {
18 "status": "fulfilled"
19 }
20]

MDN - allSettled (Node v12.9 이상)

ES2020-5. Null coalescing operator(null 병합 연산자)

null 병합 연산자는 왼쪽 피연산자가 null 또는 undefined일 때 오른쪽 연산자를 반환하고 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자입니다. 이는 왼쪽 피연산자가 falsy 값에 해당할 경우 오른쪽 피연산자를 반환하는 or(||)와는 대조됩니다.

1const foo = null ?? 'default string';
2console.log(foo);
3// expected output: "default string"
4
5const baz = 0 ?? 42;
6console.log(baz);
7// expected output: 0

MDN - Nullish coalescing operator (Node v14 이상)

ES2020-6. String.prototype.matchAll()

matchAll 메서드는 지정된 정규식에 대해 문자열과 일치하는 모든 결과의 iterator를 반환하는 메서드입니다.(캡쳐링 그룹 포함) 정규 표현식 뒤에 g flag를 사용해주어야 합니다.

1const regEx = /[a-d]/g;
2const str = 'Lorem ipsum dolor sit amet';
3const result = str.matchAll(regEx);
4
5console.log(result.next());
6{
7 "value": ["d"],
8 "done": false
9}
10console.log(result.next());
11{
12 "value": ["a"],
13 "done": false
14}
15console.log(result.next());
16{
17 "done": true
18}

MDN - matchAll

ES2020-7. 모듈 네임스페이스 export 문법

이제

1export * as stuff from './test.mjs';
2
3// 아래의 코드와 동일한 역할을 수행한다
4export { stuff };

같이 선언할 수 있습니다... 의미는 잘 모르겠..

ES2020-8. import.meta

import.meta 객체는 URL등 모듈에 대한 정보를 노출합니다.

1<script type="module" src="my-module.js">
1console.log(import.meta);
2{
3 url: "file:///home/user/my-module.js"
4}

아래와 같은 응용이 가능!

1<script type="module">
2import './index.mjs?someURLInfo=5';
3</script>
1// index.mjs
2
3new URL(import.meta.url).searchParams.get('someURLInfo'); // 5

MDN - import.meta

ES2020-8. globalThis

ES2020 전에는 전역 객체에 접근하는 표준화된 방식이 없었습니다. 브라우저에서는 window, node에서는 global, 웹 워커의 경우 self 등을 사용해 전역 객체에 접근했었습니다. ES2020부터는 어떤 환경에서든 항상 전역 객체를 참조하는 globalThis를 사용할 수 있습니다.(Node v12부터)

ES2021

아직 스펙이 정식으로 결정된 것은 아니지만 많은 제안 중에 4단계에 도달하여 다음 스펙에 포함될 예정인 것들을 몇 개 알아봅시다.

ES2021-1. String.prototype.replaceAll()

기존의 replace() 메서드는 문자열의 패턴을 다른 것으로 바꿀 수 있는 유용한 메서드였지만, 정규식을 쓰지 않으면 일치하는 첫 번째 항목만 교체가 가능했습니다. 그러나 replaceAll() 단순 문자열 패턴을 대체할 때도 일치하는 모든 문자열을 교체합니다.

1const str = 'I like my dog, my dog is very cute.';
2const newStr = str.replaceAll('dog', 'cat');
3
4console.log(newStr);
5//I like my cat, my cat is very cute.

MDN - replaceAll (chrome85, node v15 이상)

ES2021-2. Promise.any()

Promise.any()는 주어진 promise 중 하나라도 성공하면 실행을 완료하지만, 그렇지 않다면 모든 promise가 실패할 때 까지 계속됩니다. Promise.race()는 하나라도 성공 혹은 실패할 시에 종료되는 것과 차이가 있습니다.

1const promise1 = Promise.reject(0);
2const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'quick'));
3const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 500, 'slow'));
4
5const promise4 = new Promise((resolve, reject) => setTimeout(reject, 100, 'quick'));
6const promise5 = new Promise((resolve, reject) => setTimeout(reject, 500, 'slow'));
7
8const promises1 = [promise1, promise2, promise3]
9const promises2 = [promise1, promise4, promise5];
10
11Promise.any(promises1).then((value) => console.log(value)).catch(err => console.log(err));
12// 'quick'
13
14
15Promise.any(promises2).then((value) => console.log(value)).catch(err => console.log(err));
16// AggregateError: All promises were rejected

MDN - Promise.any() (chrome85, Node v15 이상)

ES2021-3. 논리 연산자와 할당 표현식

ES2021부터는 논리 연산자와 할당 표현식을 결합할 수 있습니다.

1const a = { duration: 50, title: ''};
2
3a.duration ??= 10;
4console.log(a.duration);
5// 50
6
7a.speed ??= 25;
8console.log(a.speed);
9// 25
10
11a.duration &&= 60;
12console.log(a.duration);
13// 60
14
15a.title ||= 'Logical or Assignment'
16console.log(a.title);
17// 'Logical or Assignment'

MDN - Logical nullish assignment (chrome85, Node v15 이상)

ES2021-4. 숫자 구분 기호

ES2021에는 숫자 구분 기호가 도입되었으며, 큰 자릿수 숫자를 구분하는데에 언더바를 사용하여 쉽게 표시할 수 있게 되었습니다.

1const x = 100_000;
2console.log(x)
3// 100000;

MDN 문서를 찾지 못하여 proposal 명세서를 남깁니다. TC39 - proposal-numeric-separator

ES2021-5. WeakRef

WeakRef를 통해 특정 객체에 일반 참조가 없으면 약한 참조가 남아있어도 가비지 콜렉터가 해당 객체를 메모리에서 제거한다고 합니다. 이 부분도 조금 더 자세한 공부가 필요할 것 같아서 참조 링크를 남기고, 후에 다시 자세히 설명할 기회를 가지려고 합니다. MDN - WeakRef

ES2021-6. Intl.ListFormat

각종 언어별로 목록 서식을 활성화하는 객체의 생성자라고 합니다. 직접 보는 것이 이해가 빠를 것 같습니다.

1const list = ['Apple', 'Orange', 'Banana'];
2
3console.log(new Intl.ListFormat('ko', {style:'long', type: 'conjunction'}).format(list));
4// 'Apple, Orange 및 Banana'
5console.log(new Intl.ListFormat('ko', {style:'long', type: 'disjunction'}).format(list));
6// 'Apple, Orange 또는 Banana'
7
8console.log(new Intl.ListFormat('en', {style:'long', type: 'conjunction'}).format(list));
9// 'Apple, Orange, and Banana'
10console.log(new Intl.ListFormat('en', {style:'long', type: 'disjunction'}).format(list));
11// 'Apple, Orange, or Banana'

MDN - ListFormat

ES2021-7. Intl.DateTimeFormat의 dateStyle 및 timeStyle

직접 봅시다!

1new Intl.DateTimeFormat("ko", {dateStyle: "short"}).format(Date.now());
2// '21. 6. 21.'
3new Intl.DateTimeFormat("ko", {dateStyle: "medium"}).format(Date.now());
4// '2021. 6. 21.'
5new Intl.DateTimeFormat("ko", {dateStyle: "long"}).format(Date.now());
6// "2021년 6월 21일"
7
8new Intl.DateTimeFormat("en", {dateStyle: "short"}).format(Date.now());
9// '6/21/21'
10new Intl.DateTimeFormat("en", {dateStyle: "medium"}).format(Date.now());
11// 'Jun 21, 2021'
12new Intl.DateTimeFormat("en", {dateStyle: "long"}).format(Date.now());
13// "June 21, 2021"
1new Intl.DateTimeFormat("en", {timeStyle:"short"}).format(Date.now());
2// 1:11 PM
3new Intl.DateTimeFormat("en", {timeStyle:"medium"}).format(Date.now());
4// 1:11:50 PM
5new Intl.DateTimeFormat("en", {timeStyle:"long"}).format(Date.now());
6// "1:11:50 PM GMT+9"
7
8new Intl.DateTimeFormat("ko", {timeStyle:"short"}).format(Date.now());
9// 오후 1:12
10new Intl.DateTimeFormat("ko", {timeStyle:"medium"}).format(Date.now());
11// 오후 1:12:24
12new Intl.DateTimeFormat("ko", {timeStyle:"long"}).format(Date.now());
13// "오후 1시 12분 24초 GMT+9"

마무리하며

지금까지 ES6 이후에 새로이 추가된 스펙들에 대해서 간략하게 알아보았습니다. 이 글을 작성한 시점과 업로드하는 시점은 차이가 좀 있는데요, 그 사이에 ES2021 스펙이 어느 정도 확정이 된 것 같습니다. 여러 proposal에 대한 정보는 github의 tc39에서 볼 수 있으니 관심이 있으시면 보시는 것도 좋을 것 같습니다. 최대한 확인한다고 했지만 예제나 정보에 틀린 내용이 있을 수 있는데요, 언제든지 제 메일로 제보 주시면 좋겠습니다. 읽어주셔서 감사합니다.

참조(예제 및 설명)

© 2023 by Raf. All rights reserved.