본문 바로가기
Web/JavaScript

ECMAScript 2021 추가되는 기능들 소개

by 폴우정킴 2021. 6. 14.

JavaScript의 스펙을 정의하는 ECMAScript는 모던 자바스크립트의 시작점이라고 불리는 2015년 이후 매해 6월에 Stage 4 단계에 도달한 새로운 기능들을 공식적으로 업데이트한다.

 

2021년에 업데이트되는 새로운 기능 6가지

  • String.prototype.replaceAll()
  • Private Methods
  • Promise.any
  • Numeric separator
  • Logical Assignment Operators
  • WeakRefs and FinalizationRegistry

 

1. String.prototype.replaceAll()

replaceAll() 메소드는 어떠한 패턴과 일치하는 모든 값을 replacement와 교체한 새로운 string을 반환한다.

여기서 replacement는 string이나 함수가 될 수 있다. 본래의 string 값은 변하지 않는다.

 

// 1. String.prototype.replaceAll() 
const string = "Annie, are you okay? So Annie are you okay? Are you okay?, Annie Annie, are you ok?";

console.log(string.replaceAll("Annie", "Jenny"));
//  Jenny, are you okay? So Jenny are you okay? Are you okay?, Jenny Jenny, are you ok?

 

2. Private Methods

자바스크립트의 클래스 프로퍼티는 기본적으로 public이다. 즉 기본적으로 클래스 밖에서 읽을 수도 수정될 수도 있다. 이제는 hash (#) 접두사로 private 프로퍼티를 정의할 수 있다.

 

// 2. Private Methods
class Person {
	showName() {
		console.log("My name is Paul");
	}
	#showAge() {
		console.log("I am 20 years old");
	}
	showAll() {
		this.showName();
		this.#showAge();
	}
}

const person = new Person();

person.showName() // My name is Paul

person.showAge() // TypeError: person.showAge is not a function

persone.showAll() // My name is Paul, I am 20 years old

 

3. Promise.any()

Promise 들을 순회하면서 이 중 하나의 promise가 fulfilled 된 상태가 되면 이의 resolve 값을 반환한다. 만약 모든 Promise들이 fulfilled 되지 않고 reject가 되면 AggregateError를 반환한다.

 

// 3. Promise.any() 
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("첫쨰"), Math.floor(Math.random() * 100));
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("둘째"), Math.floor(Math.random() * 100));
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("셋째"), Math.floor(Math.random() * 100));
})

try{
  (async function() {
    const result = await Promise.any([p1, p2, p3]);
    console.log(result); // 첫째 || 둘째 || 셋쨰 
  })();
} catch (error) {
  console.log(error); // AggregateError: All promises were rejected (셋다 reject 된다면)
}

 

Promise.any가 추가됨으로써 promise 세트를 다루는 비동기 연산들이 Promise.all, Promise.allSettled, Promise.race 에 이어 총 4개가 되었다. 이 중 Promise.any 는 Promise.race 와 비슷해 보이지만 분명 다른 점이 있다. 이러한 차이점을 알기 위해 먼저 fulfilled와 settled가 무엇인지 알아야 한다.

  1. fulfilled: promise가 이행된 상태
  2. rejected: promise가 어떠한 이유로 이행되지 못한 상태
  3. settled: fulfilled 되거나 rejected 된 상태

* Promise.race 는 여러 개의 promise들 중 가장 먼저 settled 된 promise를 반환한다.

* Promise.any는 여러개의 promise들 중 가장 먼저 fulfilled 된 promise를 반환한다. 하지만 fulfilled 없이 모두 rejected 된다면

   AggregateError를 반환한다.

 

4. Numeric Separators

긴 숫자를 보다 정확하게 볼 수 있기 위해 underscore를 사용할 수 있다.

 

const pay = 10000000; // 백만? 첫만? 
const payWith_ = 10_000_000;

console.log("pay", pay); // 10000000

console.log("pay", payWith_); // 10000000

console.log("pay", typeof(pay)) // Number

 

 

5. Logical Assignment Operators

수학적 연산자를 통해 x = x + y 는 x += y로 표현될 수 있다.

이제 && , || ,?? 의 논리 연산자를 사용하여 위와 같이 논리 할당을 할 수 있다.

 

let x = "파랑"; 
let y = "빨강";
let z;

x &&= y; // x 가 truthy 면 y로 바꾼다 
console.log(x) // 빨강

x ||= y; // x 가 falsy 면 y로 바꾼다
console.log(y) // 파랑

z ??= x; // z 가 undefined 거나 null 이면 x로 바꾼다
console.log(z) // 파랑

 

 

6. WeakRefs and Finalizers

WeakRefs

WeakRef 객체는 다른 객체를 약하게 참조한다는 의미로 가비지 컬렉터의 대상이 되지 않는 기존의 강한 참조와는 다른 점이 특징이다.

약한 참조는 언제 실행될지 모르는 가비지 컬렉터가 객체의 메모리를 해제시키면 참조하는 곳에서 더 이상 해당 객체를 참조할 수 없게 된다.

 

const Obj = new WeakRef({
  name: "Paul"
});

const callback = () => {
	// WeakRef 인스턴스는 deref 메소드를 통해 두가지의 값 중 하나를 반환한다
  // 1. constructor 에 전달된 객체
  // 2. 객체의 값이 가비지 컬렉터에 의해 제거됬다면 undefined
  console.log("deRef", Obj.deref().name); // "Paul" || undefiend
}

(async function(){
  await new Promise((resolve) => {
    setTimeout(() => {
      callback(); // Paul
      resolve();
    }, 100);
  });

  await new Promise((resolve) => {
    setTimeout(() => {
      callback(); // Paul || undefiend
      resolve();
    }, 5000);
  });
})();

// 브라우저와 자바스크립트의 엔진에 따라 가비지 컬렉터의 실행 시점이 다르기 때문에 
// 언제 참조가 해제될지 예상하기는 힘들다. 

 

TIP: 개발자 도구 → Performance에서 휴지통 아이콘을 누르면 강제로 가비지 컬렉터를 실행시킬 수 있다.

 

Finalizers

FinalizatiionRegistry constructor에 전달되는 콜백 함수는 register 메소드를 통해 등록한 객체가 가비지 컬렉터의 의해 메모리가 해제될 때 실행된다.

이 콜백 함수에는 register 메소드를 통해 등록한 객체의 사용을 피하고( 콜백 함수가 실행되는 시점에는 해당 객체가 메모리에서 해제되었기 때문에 참조할 수 없다 ) 별개의 값을 사용해야 한다.

 

class Person () {...};

const registry = new FinalizationRegistry((data) => {
  console.log("message", data.message);
});

(function () {
  const person = new Person();
  registry.register(person, {message:"가비지 컬렉터에 의해 해제 됨"});
})();

가비지 컬렉터가 person 인스턴스의 메모리 영역을 해지 시 -> // 가비지 컬렉터에 의해 해제 됨

 

 

 

 

참고 링크: 

 

Stage 4 새로운 기능들

https://github.com/tc39/proposals/blob/master/finished-proposals.md?utm_source=thenewstack&utm_medium=website&utm_campaign=platform 

 

tc39/proposals

Tracking ECMAScript Proposals. Contribute to tc39/proposals development by creating an account on GitHub.

github.com

 

https://thenewstack.io/ecmascript-2021-whats-next-for-javascript-webassembly/

 

ECMAScript 2021: What's Next for JavaScript? - The New Stack

The latest additions to JavaScript are mostly improvements to make working with the language more developer-friendly. And there's more: A powerful new option is designed to support WebAssembly.

thenewstack.io

 

https://backbencher.dev/javascript/es2021-new-features

 

ES2021 / ES12 New Features

Learn JavaScript, Node.js and NPM packages in depth

backbencher.dev

 

 

댓글