1. 소개
- ES9라도고 불리는 ES2018은 2018년에 소개된 ECMA Script의 2018버전이다.
- 2015만큼은 아니지만 꽤 유용한 기능들이 추가되었다. 객체에서도 나머지 연산자와 스프레드 연산자를 사용할 수 있게 되었고, 비동기 반복이 편리해졌다.
2. 기능
* Spread Properties
const obj = { x: 11, y: 22, z: 33 };
const foo = { a: 9999, ...obj };
console.log(foo);
// { a: 9999, x: 11, y: 22, z: 33 }
- 기존에 배열에서만 사용되었던 스프레드연산자가 객체에서도 사용가능하게 되었다.
- 위를 통해 편리하게 얕은복사가 가능해졌다.
* Rest Properties
const obj = { x: 11, y: 22, z: 33 };
const { x, ...args } = obj;
console.log(x); // 11
console.log(args); // {y: 22, z: 33}
- 객체 분해 할당 시에 분해 연산자를 이용하여 사용되지 않은 프로퍼티들을 묶을 수 있게 되었다.
* Promise finally
Promise.resolve()
.then(() => {
console.log("then 01");
})
.finally(() => {
console.log("finally 01");
throw new Error();
})
.then(() => {
console.log("then 02");
})
.catch(() => {
console.log("catch 01");
})
.finally(() => {
console.log("finally 02");
});
// then 01
// finally 01
// catch 01
// finally 02
- 프라미스에 finally 키워드가 추가되었다. 이는 이행될때 시행되는 then과 거절될 때 시행되는 catch 와는 전혀다른 성격을 갖고 있다. finally는 반드시 실행되는 키워드이다.
- 만일 finally 안에서 예외가 발생하면 rejected 상태로 변화하고 아래의 catch가 실행된다. 위의 코드에서 첫 번째 finally 다음의 then이 실행되지 않는 것이 바로 그 이유이다.
* for await of
const delay = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(time), time));
async function asyncFunc() {
const promises = [delay(1000), delay(1000), delay(1000)];
for await (const p of promises) {
console.log(p);
}
}
asyncFunc();
- for await of 로 주어진 iterator 에 프로미스가 포함된 경우를 처리할 수 있게 되었다. 위를 실행하면 1초뒤에 세 개의 1000이 출력된다.
- ES2018 이전에는 아래와 같이 처리했다.
const delay = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(time), time));
async function asyncFunc() {
const promises = [delay(1000), delay(1000), delay(1000)];
for (const p of promises) {
const data = await p;
console.log(data);
}
}
asyncFunc();
* Symbol asynciterator
- 이번에는 위와 달리 ES2018 이전에 비동기 이터레이터를 사용한 예제를 먼저 보자.
const delay = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(time), time));
const myIterator = {
*[Symbol.iterator]() {
for (let _ = 0; _ < 5; _++) {
yield delay(1000);
}
},
};
async function myFunc() {
for (const p of myIterator) {
const value = await p;
console.log(value);
}
}
myFunc();
- 참고로 제너레이터는 이터러블이므로 반복이 가능하다. 이를 통해 이터레이터 객체를 생성하여 반복문을 시행하였다.
- 프라미스이므로 async await 을 사용하기 위해 await 를 사용하여 value 에 할당후 console을 찍었다. 이를 for await of 로 만들 수 있을까. 이 때 사용되는 것이 Symbol.asyncIterator 이다.
const delay = (time) => new Promise((resolve, reject) => setTimeout(() => resolve(time), time));
const myIterator = {
async *[Symbol.asyncIterator]() {
for (let _ = 0; _ < 5; _++) {
yield await delay(1000);
}
}
};
async function myFunc() {
for await (const p of myIterator) {
console.log(p);
}
}
myFunc();
- asyncIterator 는 iterator와 달리 async await 키워드를 사용할 수 있다.
- asyncIterator로 구현된 이터레이터 객체는 for awiat of 를 사용할 수 있다. 만일 객체내에 Symbol.iterator 와 Symbol.asyncIterator가 동시에 구현된 경우 각각 for-of , for-await-of 시 선택된다.
- 위의 기능들 외에도 정규표현식에 몇가지 기능이 추가되었다. 그중 대표적으로 Named Capture Groups와 Unicode Property Escapes가 추가되었다.
- 정규식에서 캡쳐 그룹이 문자열 이름을 가질 수 있게 되었고, 자주 사용되는 유니코드 패턴을 제공한다. \p{Emoji}/ 와 같이 유니코드셋 카테고리명을 적어서 패턴을 사용한다. 카테고리 종류는 MDN에서 확인할 수 있다.
참고
'Language > JavaScript' 카테고리의 다른 글
<JS> 제너레이터 (0) | 2021.10.17 |
---|---|
<ES10> ES2019 Features (0) | 2021.10.11 |
<이벤트루프> 태스크 큐 : 마이크로태스크 큐 & 매크로태스크 큐 (0) | 2021.10.04 |
<이벤트루프> JS와 이벤트루프 (2) | 2021.10.03 |
<ES8> ES2017 Features (0) | 2021.09.26 |