자바스크립트 2021

June 2, 2021 - 5 minute read -

ECMAScript 2021이 밝았다.

6월 릴리즈 예정. ES2021 Candidate

String.prototype.replaceAll()

지금 존재하는 String.prototype.replace()는 첫 번째로 만나는 스트링만 대체한다.
그래서 보통 정규 표션식 /regexp/g)을 사용하는 약간의 번거로움이 있었다.

    
    const str = 'My father is father';
    const newStr = str.replace('father', 'mother');
    console.log(newStr); // My mother is father;
    
    const str2 = 'My father is father';
    const newStr2 = str.replace(/father/g, 'mother');
    console.log(newStr2); // My mother is mother;
    

이제 replaceAll 메서드가 추가된다.

    const str = 'My father is father';
    const newStr = str.replaceAll('father', 'mother');
    console.log(newStr); // My mother is mother;
    

숫자 구분자 (Numeric Separators)

긴 숫자를 쓸 때 ‘_‘ 를 이용해 가독성을 높여주는 기능이 나온다.

    const longNum = 1_000_000_000;
    console.log(longNum)// 1000000000;
    const floatNum = 12_3_45.56;
    console.log(floatNum)// 12345.56
    

논리 할당 연산자(Logical Assignment Operator)

논리 연산자와 할당 표현식을 결합한 연산자가 추가 된다.
아직 익숙하지 않아서 그런지, 약간은 헷갈리는 느낌이 있다…
‘&&’, ‘||’ 는 값을 할당 받는 변수의 falsy, truthy를 판단하고 ’??’ 는 undefined나 null일 경우를 판단하여 값을 할당한다.

    let x = 2;
    let y = 1;
    x &&= y;
    console.log(x) // 1;
    
    //위 코드를 풀어쓰면 아래와 같다.
    
    if (x) {
        x = y;
    }
    
    let x = 0;
    let y = 1;
    x ||= y;
    console.log(x) // 1;

    //위 코드를 풀어쓰면 아래와 같다.
    
    if (!x) {
        x = y;
    }
    
    let x;
    let y = 1;
    x ??= y;
    console.log(x) // 1;

    //위 코드를 풀어쓰면 아래와 같다.
    
    if (x === undefined || x === null) {
        x = y;
    }
    

Promise.any

기존의 Promise.race 처럼, 프로미스 객체로 이뤄진 배열 중 먼저 이행된 프로미스 객체의 결과를 반환한다. Promise.race 와 다른 점은, 먼저 거절된 객체가 있어도 즉시 거절 하지 않는다.

    const p1 = new Promise((resolve, reject) => {
      setTimeout(() => reject('A'), 100);
    });
    const p2 = new Promise((resolve, reject) => {
      setTimeout(() => resolve('B'), 200);
    });
    const p3 = new Promise((resolve, reject) => {
      setTimeout(() => resolve('C'), 300);
    });
    
    (async function() {
        try {
            const result = await Promise.any([p1, p2, p3]);
            console.log(result); 
        } catch (e) {
            console.log('error', e);
        }
        
        // 'B'
    })();
    
    (async function() {
        try {
            const result = await Promise.race([p1, p2, p3]);
            console.log(result);        
        } catch (e) {
            console.log('error', e);
        }
        
        // 'error, A'
    })();
    

WeakRef

자바스트립트의 가비지 컬렉터는 참조가 걸려있으면 절대 건드리는 법이 없었다.
WeakRef는 ‘약함 참조’로 가비지 컬렉팅의 대상이 된다.
주의해야 할 점은, 가비지 컬렉터가 자바스트립트 엔진에 따라 작동이 상이하기 때문에, 원치 않은 결과가 발생할 수 있다.
실제로, 저자조차 사용을 권하지는 않는다. proposal-weakrefs/

    let obj = {
        name: 'dj',
    };
    const weakObj = new WeakRef(obj);
    obj = null;
    const timer = setInterval(() => {
        const weakR = weakObj.deref();
        if (weakR) {
            console.log(weakR.name);
        } else {
            console.log('Collected');
            clearInterval(timer)
        }
    }, 1000);
    

Finalizers

garbage collection 이후 콜백을 호출하도록 요청할 수 있게 됐다. 크롬 개발자 도구 퍼포먼스 탭에서 쓰레기통 버튼을 눌러 테스트(garbage collection) 해볼 수 있다.

    const registry = new FinalizationRegistry((value) => {
      console.log(value);
    });
    (function () {
      registry.register({}, 'hello');
    })();
    

Resource

https://ui.toast.com/weekly-pick/ko_20210202
https://github.com/tc39/proposals/blob/master/finished-proposals.md
https://backbencher.dev/javascript/es2021-new-features