티스토리 뷰
ES2023있으니 어서 배웁시다.
원문: https://javascript.plainenglish.io/es2023-is-here-hurry-up-to-learn-2de85c61f0ae
서문
ES6는 2015년도에 제안되었으며, 이 논리에 따르면 ES2023은 ES14로 불려야 되지만 혼동을 피하기 위해 이름에 연도를 사용합니다. ES 표준에 집중했던 때를 돌이켜보면, 여전히 ES6에 머물러 있습니까?
ES 표준이 되풀이 되는 것을 위해 최근에 어떤 새로운 특징이 추가되었는지 보겠습니다.
ES2023
2023년도에 완료될 제안들
Array가 수정되면 수정본을 반환
Array, TypedArray에는 다음과 같이 Array 자체를 변경하는 다양한 방법들(sort/splice, etc)이 있습니다.:
const array = [3, 2, 1];
const sortedArray = array.sort();
// [1, 2, 3]
console.log(sortedArray);
// 본래의 array 또한 [1, 2, 3]이 됩니다.
console.log(array);
array 자체를 변경하고 싶지 않으면 다음과 같이 할 수 있습니다.:
const array = [3, 2, 1];
const sortedArray = array.toSorted();
// [1, 2, 3]
console.log(sortedArray);
// 본래의 array는 [3, 2, 1]로 유지됩니다.
console.log(array);
유사한 방법들은 여기에 포함되어 있습니다.:
T.prototype.toReversed() -> T
T.prototype.toSorted(compareFn) -> t
T.prototype.toSpliced(start, deleteCount, ...items) -> T
T.prototype.with(index, value) -> T
reverse/sort/splice는 이해할 수 있지만 with는 무엇입니까? 이해를 위해 예시를 보시면 됩니다.:
const array = [1, 2, 3];
const newArray = array.with(1, false);
// [1, false, 3]
console.log(newArray);
// 본래의 array는 [1, 2, 3]으로 유지됩니다.
console.log(array);
WeakMap은 Symbol을 키로서 지원합니다.
WeakMap 원래 object 타입의 키만 지원했지만 지금은 Symbol 타입도 키로써 지원합니다.
const weak = new WeakMap();
weak.set(Symbol('symbol1'), {});
Hashbang syntax
Hashbang은 Shebang으로도 불리우며, 파일을 실행하기 위해 사용할 인터프리터를 지정하는 #!
파운드 기호와 느낌표로 구성된 일련의 문자로 이루어져 있습니다.:
// hashbang.js
#!/usr/bin/env node
console.log('hashbang');
// nohashbang.js
console.log('no hashbang')
Hashbang 없이 터미널에서 실행은 node 명령어로 실행해야 합니다.:
끝에서 부터 봅시다.
두 함수는 findLast / findLastIndex와 관련이 있습니다.
const array = [1, 2, 3];
array.findLast((n) => n.value % 2 === 1);
array.findLastIndex((n) => n.value % 2 === 1);
ES2022
예외 체인
예시를 바로 보면, err0.cause
를 통해 err1
을 얻을 수 있습니다.; 만약 이 예외가 계속 반복된다면, err1.cause.cause
... 모든 관련 예외를 얻을 수 있습니다.
function willThrowError() {
try {
// do something
} catch (err0) {
throw new Error('one error', { cause: err });
}
}
try {
willThrowError();
} catch (err1) {
// You can get err0 through err1.caus
}
클래스 정적 코드 블록
복잡한 정적 property/method 초기 논리를 구현하기 위한 정적 코드 블록:
// 정적 코드 블록이 아닐때,
// 초기 에디터는 클래스 정의에서 나누어 집니다.
class C {
static x = ...;
static y;
static z;
}
try {
const obj = doSomethingWith(C.x);
C.y = obj.y
C.z = obj.z;
}
catch {
C.y = ...;
C.z = ...;
}
// 정적 코드 블록을 사용하면, 코드 논리는 더 집중됩니다.
class C {
static x = ...;
static y;
static z;
static {
try {
// 여기서 this는 C의 인스턴스가 아닌 C를 나타냅니다.
const obj = doSomethingWith(this.x);
this.y = obj.y;
this.z = obj.z;
}
catch {
this.y = ...;
this.z = ...;
}
}
}
특별한 기능은: private properties에 접근할 수 있습니다.
let getPrivateField;
class D {
#privateField;
constructor(v) {
this.#privateField = v;
}
static {
getPrivateField = (d) => d.#privateField;
}
}
getPrivateField(new D('private value'));
// → private value
Object.hasOwn
특히 오픈 소스 라이브러리에서 이러한 사용을 볼 수 있습니다.
let hasOwnProperty = Object.prototype.hasOwnProperty;
if (hasOwnProperty.call(object, 'foo')) {
console.log('has property foo');
}
Object.hasOwn을 사용하면, 간단하게 사용할 수 있습니다.:
if (Object.hasOwn(object, 'foo')) {
console.log('has property foo');
}
.at
은 특정 인덱스의 요소를 반환합니다.
인덱스 가능한 유형들 (String/Array/TypedArray)은 at
을 통해 특정 인덱스의 요소를 읽을 수 있고, 음수를 사용한 수 있습니다.
// return 4
[1, 2, 3, 4].at(-1);
private property 존재하는지를 결정
in
키워드로 판단할 수 있습니다.
class C {
#brand = 0;
static isC(obj: C) {
return #brand in obj;
}
}
Top-level await
async
패키지 없이, 다음과 같이 await
를 사용할 수 있습니다.:
function fn() {
return Promise.resolve();
}
// 이전에는 IIFE를 통해 구현해야 했습니다.
(async function () {
await fn();
})();
// top-level await가 제공된 후에, 직접적으로 사용할 수 있습니다.
await fn();
정규식 slicing
정규 매칭을 통해 매칭된 문자열을 얻을 수 있고, slicing을 통해 기존 문자열에서 이 문자열의 위치를 얻을 수 있습니다.
const re1 = /a+(z)?/d;
const s1 = 'xaaaz';
const m1 = re1.exec(s1);
ES2021
숫자 구분 기호
숫자가 너무 길다면, 읽는 것이 불편할 수 있어 _
구분 기호를 이용 할 수 있습니다.:
// 1000000
console.log(1_000_000);
// 구분 기호가 첫 / 마지막 글자가 아닌 이상 어디든 위치할 수 있습니다.
1_000000000_1_2_3;
논리 연산자 할당
산술 연산자 할당이랑 유사하지만, 논리 연산자 각각 비교할 수 있는 단락 기능을 갖습니다.
// 산술 연산자
let x = 1;
//x 은 2
x += 1;
// 논리 연산자
let x = 1;
// x는 여전히 1, x는 참 값이기 때문
// x = 1 || 3과 같은 단락 기능
x ||= 3;
WeakRef
객체를 가비지 컬렉터에서 수집되는 것을 막지 않고 참조할 수 있게 해주는 약한 참조.
let obj = { name: 'obj1' };
let weakRef = new WeakRef(obj);
// 객체 참조 얻기
// 객체 참조를 반복하면 undefined를 얻을 것입니다.
weakRef.deref();
Promise.any
몇몇 다른 함수들과 비교합니다.
Promise.any
하나의 입력이 해결한 것과 같이 해결합니다.
Promise.any([
Promise.reject('reject 1'),
Promise.reject('reject 2'),
Promise.reject('reject 3'),
Promise.resolve('1'),
Promise.resolve('2'),
]).then(
(first) => {
// 해결한 것 같이 여기서 실행됩니다.
// prints 1
console.log(first);
},
(error) => {
// 모두 reject되면 여기서 실행됩니다.
console.log(error);
}
);
Promise.allSettled
입력된 promise가 reject 인지 reslove인지 상관없이 then까지 롤업됩니다.
Promise.allSettled([
Promise.resolve('1'),
Promise.resolve('2'),
Promise.reject('e1'),
Promise.resolve('3'),
Promise.resolve('4'),
]).then((res) => {
console.log('then', res);
});
Promise.all
reject가 있으면 then reject가 됩니다. 다음 예제는 catch로 이동합니다.:
Promise.all([
Promise.resolve('1'),
Promise.resolve('2'),
Promise.reject('e1'),
Promise.resolve('3'),
])
.then((res) => {
console.log('then', res);
})
.catch((err) => {
// catch e1 출력
console.log('catch', err);
});
Promise.race
reject(or resolve)가 있으면, then reject(or resolve)가 됩니다.
function delay(type: 'resolve' | 'reject', timeout: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (type === 'reject') {
reject(type);
} else {
resolve(type);
}
}, timeout);
});
}
// print then resolve
Promise.race([delay('resolve', 1000), delay('reject', 2000)])
.then((res) => {
console.log('then', res);
})
.catch((err) => {
console.log('catch', err);
});
// print catch reject
Promise.race([delay('resolve', 2000), delay('reject', 1000)])
.then((res) => {
console.log('then', res);
})
.catch((err) => {
console.log('catch', err);
});
String.prototype.replaceAll;
매칭된 모든 문자열 변환
// 12c12d12
'abcabdab'.replaceAll('ab', '12');
// 12cabdab
'abcabdab'.replace('ab', '12');
ES2020
import.meta
host 관련 모듈 메타 정보 제공
연산자와 병합되는 Null 값
오른쪽 피연산자는 왼쪽 피연산자가 null 또는 undefined인 경우에만 반환됩니다.
// "default"
let a = null || 'default';
// "default"
let a = null ?? 'default';
// "default"
let a = '' || 'default';
// ""
let a = '' ?? 'default';
// "default"
let a = 0 || 'default';
// 0
let a = 0 ?? 'default';
Optional chain
코드에서 보겠습니다.
// optional chaining 없이
const street = user.address && user.address.street;
// optional chaining
const street = user.address?.street;
BigInt
2의 53제곱근 보다 큰 수(js Number
유형에서 나타낼 수 있는 가장 큰 수)를 나타낼 수 있습니다.
// 숫자 마지막에 n 추가
const theBiggestInt = 9007199254740991n;
// BigInt 구조체 사용
const alsoHuge = BigInt(9007199254740991);
import()
모듈들이 런타임에서 동적으로 로드됩니다.
String.prototype.matchAll
match
는 오직 매칭된 문자열을 리턴하고, 그룹 정보는 없지만; matchAll
은 매칭된 문자열과 그룹 정보와 함께 리턴합니다.
요약
ES2016 ~ ES2019는 하나씩 나열되지 않았지만 모두가 숙지해야 합니다. 명확하지 않는 특징이 있으면 메시지를 남겨주시면 됩니다.
참고 문서
github.com/tc39/propos…
More content at PlainEnglish.io.
Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.
Interested in scaling your software startup? Check out Circuit.
'활동 > FE 번역' 카테고리의 다른 글
[번역] Experiments with the JavaScript Garbage Collector (0) | 2023.05.14 |
---|---|
[번역] A Complete Guide to useEffect (미완성) (3) | 2023.03.28 |
[번역] Better Configuration in TypeScript with the `satisfies` Operator (0) | 2023.02.26 |
[번역] Deep Cloning Objects in JavaScript, the Modern Way (0) | 2023.02.19 |
[번역] Before You memo() (0) | 2023.02.13 |