이번 포스팅에선 ES9 의 기능들에 대해 알아보겠습니다. 나온진 꽤 됐지만 쓰는 기능도 있고 처음 보는 기능 (관심이 부족했는지..) 도 있어 적어보려 합니다.
- Object rest/spread properties
ES6 때부터 spread operator 와 rest parameters 는 도입이 되었었습니다. 먼저 이 두 문법부터 간단히 보도록 하겠습니다.
const list1 = [1, 2, 3];
const list2 = [...list1, 4, 5, 6];
console.info(list2); // [1, 2, 3, 4, 5, 6]
위는 spread operator 의 예시입니다. 전개 연산자라고도 하는데 이름 그대로 Iterable 한 배열의 프로퍼티를 펼치는 역할을 합니다. 단순 펼치는게 아니라 복사해 새로운 배열을 만들어내죠.
const list1 = [1, 2, 3, 4, 5, 6];
const [one, ...rest] = list1;
console.info(one); // 1
console.info(rest); // [2, 3, 4, 5, 6]
이번엔 rest parameters 의 예시입니다. 이것 또한 말 그대로 변수로 할당한 부분을 제외한 나머지 프로퍼티들을 합쳐서 하나로 받을 수 있는 문법입니다.
ES9 에 추가된 Object rest/spread properties 라는 기능은 위의 기능을 배열이 아닌 객체에서도 쓸 수 있게 된 것 입니다.
const test1 = { id1: 1 };
const test2 = { ...test1, id2: 2 };
const test3 = { ...test2, id3: 3 };
console.info(test1); // { id1: 1 }
console.info(test2); // { id1: 1, id2: 2 }
console.info(test3); // { id1: 1, id2: 2, id3: 3 }
const test4 = { id1: 1, id2: 2, id3: 3 };
const { id1, ...rest } = test4;
console.info(id1); // 1
console.info(rest); // { id2: 2, id3: 3 }
배열에서 많이 써왔던 기능이고, 지금은 object destructuring 또한 너무 흔하게 사용하기 때문에 눈에 아주 익숙한 문법들입니다.
이런 기능들을 통해 객체를 복사할 때 Object.assign 을 따로 사용하지 않아도 되고, JS 에서 가변인자를 받는 함수를 처리할 손쉽게 만들고 다룰 수 있게 되었습니다. 물론 그전에도 할 수 없었던 건 아니지만, 여러모로 편해진 ... syntax 입니다.
-AsyncIterator
JS 에서 Iterable 하다는 것은 Symbol.Iterator 가 구현되어 있는 객체이고, 이러한 객체는 Iterator 의 next 메서드를 통해 Iterable 한 객체의 다음 값에 접근할 수 있게 됩니다. 이 값은 실제로 value 와 done 으로 구분됩니다.
const list1 = [1, 2, 3];
const iterator = list1[Symbol.iterator]();
const test1 = iterator.next();
console.info(test1); // { value: 1, done: false }
const test2 = iterator.next();
console.info(test2); // { value: 2, done: false }
const test3 = iterator.next();
console.info(test3); // { value: 3, done: false }
const test4 = iterator.next();
console.info(test4); // { value: undefined, done: true }
const test5 = iterator.next();
console.info(test5); // { value: undefined, done: true }
위는 기존 Iterator 에 대한 간단한 예시입니다. list1 배열을 강제로 Iterator 로 만들어 next 를 호출했을 때, 각각 value 1 2 3 에 순차적으로 접근하고 그때까진 done 의 상태가 끝나지 않았으므로 false 를 반환하다가 전부 끝나면 true 로 변하죠. 이미 끝난 iterator 에선 next 를 계속 호출해도 undefined value 를 반환하는 것을 볼 수 있습니다.
하지만 이 Iterator 는 동기식에만 적용 가능했고, 비동기식에는 적용되지 않았습니다. (물론 제네레이터가 있긴 합니다만..)
ES9 에서 소개되는 AsyncIterator 는 이제 이 Iterator 를 비동기식에도 적용할 수 있게 된 것입니다.
const test1 = () => {
return new Promise(resolve => {
setTimeout(() => {
console.info('test1');
resolve(1);
}, 1000);
});
};
const test2 = () => {
return new Promise(resolve => {
setTimeout(() => {
console.info('test2');
resolve(2);
}, 3000);
});
};
const test3 = () => {
return new Promise(resolve => {
setTimeout(() => {
console.info('test3');
resolve(3);
}, 500);
});
};
(async () => {
const promises = [test1(), test2(), test3()];
for await (const item of promises) {
console.info(item);
// 1, 2, 3
// 하지만 내부 console.info 는 test3, test1, test2
}
})();
for await 문법을 제공함으로써 위와 같이 다음 값에 접근할 때마다 반환되는 promise 에 암시적으로 await 가 적용됩니다.
- Promise.prototype.finally
const test1 = (id) => {
return new Promise((resolve, reject) => {
if (id < 10) {
resolve('ok');
} else {
reject('error');
}
});
};
test1(3).then(result => {
console.info(result); // 'ok'
}).catch (err => {
console.error(err);
}).finally(() => {
console.info('finally'); // 'finally'
});
test1(11).then(result => {
console.info(result);
}).catch (err => {
console.error(err); // 'error'
}).finally(() => {
console.info('finally'); // 'finally'
});
새로이 추가된 Promise.prototype.finally 메서드에서는 Promise 가 resolve 혹은 reject 되는지와는 상관없이 무조건 지정된 콜백 함수가 호출됩니다. 위 예시는 좀 발로 만들긴했는데.. 두 케이스 모두 finally 가 호출되는 것을 볼 수 있습니다.
try - catch 문에서의 finally 와 유사하고, promise 가 처리된 이후 무조건 한번 실행되기에 할당한 리소스나 커넥션등을 처리할 때 유용하게 사용할 수 있을 것 같습니다.
- 정규표현식 dotAll Flag
console.info(/foo.bar/.test('foo\nbar')); // false
console.info(/foo.bar/s.test('foo\nbar')); // true
정규표현식에 새롭게 추가된 s flag (dotAll) 입니다.
원래 . 표현식 에선 개행문자를 제외한 모든 문자였지만, s flag 를 달면 개행문자도 포함하게 됩니다.
정규표현식에는 이 외에도 named capture groups, unicode property escapes, look-behind assertion 등이 추가되었지만
원체 이쪽은 잘 안쓰다보니 dotAll flag 정도만 보고 넘어가도록 하겠습니다.
'Backend > Javascript' 카테고리의 다른 글
ES11 (ES2020) (0) | 2022.03.05 |
---|---|
ES10 (ES2019) (0) | 2022.02.27 |
ECMAScript (0) | 2022.02.12 |
TC39 Process (0) | 2022.02.07 |
ES2022 (0) | 2022.01.30 |