ECMAScript

장세진·2023년 6월 20일
1

JavaScript

목록 보기
12/12
post-thumbnail

ECMAScript

  • Ecma 인터내셔널은 정보 통신에 대한 표준을 제정하는 비영리 표준화 기구이다.
  • ECMA-262Ecma 인터내셔널 에 의해 제정된 하나의 기술 규격의 이름으로, 범용 목적의 스크립트 언어에 대한 명세를 담고 있다.
  • ECMAScriptEcma 인터내셔널 에 의해 제정된 ECMA-262 기술 규격에 의해 정의된 범용 스크립트 언어이다.
  • ECMAScript 는 스크립트 언어가 준수해야 하는 규칙, 세부 사항 및 지침을 제공한다.
  • JavaScriptECMAScript 사양을 준수하는 범용 스크립팅 언어이다.
  • 스크립트 언어는 독립된 시스템에서 사용자가 직접 프로그램을 의도에 따라 작동하도록 특별히 설계된 프로그래밍 언어이다.

결론

Ecam 인터네셔널 (정보 통신에 대한 표준을 제정하는 비영리 표준화 기구) >
ECMA-262 (범용 목적의 스크립트 언어에 대한 명세) >
ECMAScript (ECMA-262 기술 규격에 의해 정의된 범용 스크립트 언어, 스크립트 언어가 준수해야 하는 규칙과 세부 사항 및 지침 제공) >
JavaScript (ECMAScript 사양을 준수하는 범용 스크립팅 언어)

Babel

JavaScript 엔진 에는 여러 종류가 있다. Google Chrome의 V8, Mozilla Firefox의 SpiderMonkey, Microsoft Edge의 Chakra 등이 있는데 각각의 엔진은 모두 수행능력이 차이가 나고 무엇보다도 지원되는 ECMAScript 가 다르다. 엔진을 고려하지 않고 ES6 코드를 사용하게 될 경우 오류가 발생할 수 있다. 따라서 컴파일 단계를 거쳐서 ES6 코드를 ES5 로 변환시켜 엔진을 돌려야 하는 일이 생길 수 있는데 이때 사용하는것이 Babel 이다.

ES2016 (ES7)

  • ECMAScript 2016은 Ecma TC39의 새로운 연간 릴리스 주기 및 공개 개발 프로세스에 따라 릴리스된 최초의 ECMAScript 에디션
  • 새로운 지수 연산자 추가, Array.prototype에 includes 메서드 추가

Array.prototype.includes()

[1].includes(1); // true 

지수 연산자

2**10 // 1024

ES2017 (ES8)

  • ECMAScript 2017은 Async Functions, Shared Memory, Atomics와 함께 더 작은 언어 및 라이브러리 개선 사항, 버그 수정, 편집 업데이트를 도입함.
  • 비동기 함수는 약속 반환 함수에 대한 구문을 제공하여 비동기 프로그래밍 환경을 개선
  • Object.values, Object.entries 메서드가 추가
  • Object.getOwnPropertyDescriptors 추가

async/await

async getData() {
  const res = await api.getTableData(); // await asynchronous task 
  // do something
}

Object.values()

Object.values({a: 1, b: 2, c: 3}); // [1, 2, 3]

Object.entries()

Object.entries({a: 1, b: 2, c: 3}); // [["a", 1], ["b", 2], ["c", 3]]

Object.getOwnPropertyDescriptors()

개체의 모든 속성에 대한 설명자를 가져오거나 개체의 속성이 없는 경우 빈 개체를 반환.

let user = { name: "John"};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');

console.log(JSON.stringify(descriptor, null, 2));
/* property descriptor:
{
  "value": "John",
  "writable": true,
  "enumerable": true,
  "configurable": true
}
*/

SharedArrayBuffer object

멀티 스레드간에 메모리 공유를 위해 사용. 주요 브라우저에서 기본적으로 비활성화 되어있음.

/** 
** @param {*} length The size of the array buffer created, in bytes. 
** @Returns {ShareDarrayBuffer} A new ShareDarrayBuffer object of specified size. Its contents are initialized to 0. */
new SharedArrayBuffer(10)

MDN SharedArrayBuffer
만화로 소개하는 ArrayBuffer 와 SharedArrayBuffer

Atomic Object

Atomics 개체는 ShareDarrayBuffer 개체에서 원자적 작업을 수행하는 데 사용되는 정적 메서드 집합을 제공함.

MDN Atomics

String padding

문자열 끝 부분이나 시작 부분을 다른 문자열로 채워 주어진 길이를 만족하는 새로운 문자열을 만들어낼 수 있다.

"hello".padStart(6); // " hello"
"hello".padEnd(6); // "hello "
"hello".padStart(3); // "hello" // 문자열 길이보다 목표 문자열 길이가 짧다면 채워넣지 않고 그대로 반환
"hello".padEnd(20, "*"); // "hello***************" // 사용자가 지정한 값으로 채우는 것도 가능

Trailing Comma

JavaScript는 초기부터 배열 리터럴에 trailing comma를 허용했으며, ECMAScript 5부터는 객체 리터럴, ECMAScript 2017부터는 함수의 매개변수에도 허용

function f(p) {}
function f(p,) {}

(p) => {};
(p,) => {};

ES2018 (ES9)

  • AsyncIterator 프로토콜 및 비동기 생성기를 통한 비동기 반복 지원 도입 for-await-of
  • 객체 Rest 및 Spread 속성이 포함
  • dotAll또한 플래그, 명명된 캡처 그룹, 유니코드 속성 이스케이프 및 look-behind 어설션 의 4가지 새로운 정규식 기능이 포함

Asynchronous iteration

async function process(array) { 
  for await (let i of array) { 
    // doSomething(i); 
  }
}

Promise.finally()

Promise가 처리되면 충족되거나 거부되는지 여부에 관계없이 지정된 콜백 함수가 실행됨.

Promise.resolve().then().catch(e => e).finally();

Rest/Spread

const myObj = { a: 1, b: 3, c: 'cc', d: 100 };

const {a, b, ...z} = myObj;
console.log(z); // { "c": "cc", "d": 100 }

const spread = {  ...myObj,  a: 10,  e: 30,};
console.log(spread); // { "a": 10, "b": 3, "c": "cc", "d": 100, "e": 0 }

정규식 기능 개선 및 추가

RegExp lookbehind assertions

앞에 오는 항목에 따라 문자열 일치

// ?= 특정 하위 문자열이 뒤에 오는 문자열을 일치시키는데 사용
/Roger(?=Waters)/
/Roger(?= Waters)/.test('Roger is my dog') //false
/Roger(?= Waters)/.test('Roger is my dog and Roger Waters is a famous musician') //true

// ?! 문자열 뒤에 특정 하위 문자열이 오지 않는 경우 일치하는 역 연산을 수행
/Roger(?!Waters)/
/Roger(?! Waters)/.test('Roger is my dog') //true
/Roger(?! Waters)/.test('Roger Waters is a famous musician') //false

// ?<= 새로 추가된 표현식
/(?<=Roger) Waters/
/(?<=Roger) Waters/.test('Pink Waters is my dog') //false
/(?<=Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //true

// ?<! 새로 추가된 표현식
/(?<!Roger) Waters/
/(?<!Roger) Waters/.test('Pink Waters is my dog') //true
/(?<!Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //false

유니코드 속성 이스케이프 \p{…} 및 \P{…}

// ASCII
/^\p{ASCII}+$/u.test('abc')   //✅
/^\p{ASCII}+$/u.test('ABC@')  //✅
/^\p{ASCII}+$/u.test('ABC🙃') //❌

// HEX
/^\p{ASCII_Hex_Digit}+$/u.test('0123456789ABCDEF') //✅
/^\p{ASCII_Hex_Digit}+$/u.test('h')                //❌

// Emoji, ppercase, Lowercase, White_Space, Alphabetic
/^\p{Lowercase}$/u.test('h') //✅
/^\p{Uppercase}$/u.test('H') //✅

/^\p{Emoji}+$/u.test('H')   //❌
/^\p{Emoji}+$/u.test('🙃🙃') //✅

// Script
/^\p{Script=Greek}+$/u.test('ελληνικά') //✅
/^\p{Script=Latin}+$/u.test('hey') //✅

명명된 캡처 그룹(named capture group)

ES2018에서는 결과 배열의 슬롯을 할당하는 대신 캡처 그룹을 이름에 할당할 수 있음

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = re.exec('2015-01-02')

// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';

s 플래그(dotAll)

.표현식은 개행문자를 제외한 모든 문자였으나, s플래그를 달면 개행식도 포함하게 된다.

/hi.welcome/.test('hi\nwelcome') // false
/hi.welcome/s.test('hi\nwelcome') // true

ES2019 (ES10)

  • Array.prototype.{flat,flatMap}
  • Optional catch binding
  • Object.fromEntries()
  • String.prototype.{trimStart,trimEnd}
  • Symbol.prototype.description
  • JSON improvements
  • Well-formed JSON.stringify()
  • Function.prototype.toString()

Array.prototype.{flat,flatMap}

// flat()
['Dog', ['Sheep', 'Wolf']].flat()
//[ 'Dog', 'Sheep', 'Wolf' ]

// flatMap()
let arr1 = ["it's Sunny in", "", "California"];

arr1.map(x=>x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]

arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

선택적 catch 할당(Optional catch binding)

try {
  //...
} catch /*(e)*/ {
  //handle error
}

Object.fromEntries()

const entries = new Map([
  ['foo', 'bar'],
  ['baz', 42]
]);

const obj = Object.fromEntries(entries);

console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }

String.prototype.{trimStart,trimEnd}

// trimStart()
'Testing'.trimStart() //'Testing'
' Testing'.trimStart() //'Testing'
' Testing '.trimStart() //'Testing '
'Testing '.trimStart() //'Testing '

// trimEnd()
'Testing'.trimEnd() //'Testing'
' Testing'.trimEnd() //' Testing'
' Testing '.trimEnd() //' Testing'
'Testing '.trimEnd() //'Testing'

Symbol.prototype.description

심벌 객체의 description은 해당 심벌 객체의 설명을 반환한다.

Symbol('desc').toString();   // "Symbol(desc)"
Symbol('desc').description;  // "desc"

JSON 개선사항(JSON improvements)

이 변경 이전에는 JSON 으로 구문 분석된 문자열에서 줄 구분 기호(\u2028) 및 단락 구분 기호(\u2029)가 허용되지 않았다. 이제 JSON.parse()를 사용하면 해당 문자 SyntaxError가 JSON 표준에 정의된 대로 올바르게 구문 분석된다.

Well-formed JSON.stringify()

잘못된 형식의 유니코드 문자열을 반환하지 않도록 JSON.stringify를 변경되었다.

JSON.stringify("\uD800"); // 변경 전 --> '"�"' // 잘못된 형식의 유니코드 문자를 반환
JSON.stringify("\uD800"); // 변경 후 --> '"\ud800"' // 유효한 유니코드를 반환

Function.prototype.toString()

toString() 메서드는 함수의 소스 코드를 나타내는 문자열을 반환한다. ES2016까지는 소스 코드에서 주석이나 공백 문자를 제거했지만, ES2019에서 개정되어 문자열에 주석 등도 포함된다.

function /* this is bar */ bar() {}

// old
bar.toString() //'function bar() {}

// new
bar.toString() // 'function /* this is bar */ bar () {}'

ES2020 (ES11)

  • BigInt
  • Dynamic Import
  • Optional Chaining
  • Promise.allSettled
  • Nullish Coalescing
  • String.protype.matchAll
  • Module Namespace Exports
  • import.meta
  • globalThis

BigInt

BigInt는 정수 리터럴의 뒤에 n을 붙이거나(10n) 함수 BigInt()를 호출해 생성할 수 있다.

BigInt와 Number는 어떤 면에서 비슷하지만 중요한 차이점이 있습니다. 예컨대 BigInt는 내장 Math객체의 메서드와 함께 사용할 수 없고, 연산에서 Number와 혼합해 사용할 수 없습니다. 따라서 먼저 같은 자료형으로 변환해야 합니다. 그러나, BigInt가 Number로 바뀌면 정확성을 잃을 수 있으니 주의해야 합니다. 또한 bigDecimal이 아니기 때문에 소수점 이하는 언제나 버립니다.

const theBiggestInt = 9007199254740991n;
const bigintSum = theBiggestInt + 1n; // 9007199254740992n
const alsoHuge = BigInt(9007199254740991); // 9007199254740991n
typeof bigintSum // "bigint"

Dynamic Import

ES2020 부터는 필요할 때 모듈을 동적으로 가져올 수 있다.

if (condition1 && condition2) {
  const module = await import('./path/to/module.js');
  module.doSomething();
}

Optional Chaning

?. 연산자는 . 체이닝 연산자와 유사하게 작동하지만, 만약 참조가 nullish(null 또는 undefined)이라면, 에러가 발생하는 것 대신에 표현식의 리턴 값은 undefined로 단락된다. 함수 호출에서 사용될 때, 만약 주어진 함수가 존재하지 않는다면, undefined를 리턴한다.

const adventurer = {
  name: 'Alice',
  cat: { name: 'Dinah' }
};

const catName = adventurer.cat?.name; // 'Dinah'
const dogName = adventurer.dog?.name; // undefined

Promise.allSettled

Promise.allSettled() 메서드는 주어진 모든 프로미스를 이행하거나 거부한 후, 각 프로미스에 대한 결과를 나타내는 객체 배열을 반환한다.

const promiseArr = [
  new Promise((resolve, reject) => setTimeout(resolve, 1000, 'abc')),
  new Promise((resolve, reject) => setTimeout(reject, 2000)),
  new Promise((resolve, reject) => setTimeout(resolve, 3000)),
];

Promise.allSettled(promiseArr).then(data => console.log(data));
[
  {
    "status": "fulfilled",
    "value": "abc"
  },
  {
    "status": "rejected"
  },
  {
    "status": "fulfilled"
  }
]

Nullish Coalescing Operator

널 병합 연산자 (??) 는 왼쪽 피연산자가 null 또는 undefined일 때 오른쪽 피연산자를 반환하고, 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자이다.

let user = { u1: 0, u2: false, u3: null, u4: undefined u5: '', }
let u1 = user.u1 ?? 'user 1' // 0
let u2 = user.u2 ?? 'user 2' // false 
let u3 = user.u3?? 'user 3' // user 3 
let u4 = user.u4?? 'user 4' // user 4
let u5 = user.u5?? 'User 5' // ''

String.protype.matchAll

matchAll 메서드는 지정된 정규식에 대해 문자열과 일치하는 모든 결과의 iterator를 반환하는 메서드입니다.(캡쳐링 그룹 포함) 정규 표현식 뒤에 g flag를 사용해주어야 합니다.

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];

console.log(array[0]); // expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1]); // expected output: Array ["test2", "e", "st2", "2"]

Module Namespace Exports

export * as A from "./moduleA";
export * as B from "./moduleA";

import { A, B } from "./modules";
console.log(A.a); // 1
console.log(A.b); // 2
console.log(B.b); // 3
console.log(B.c); // 4

import.meta

현재 모듈파일의 메타정보를 가져올 수 있다.

<script type="module" src="my-module.js">
console.log(import.meta); // { url: "file:///home/user/my-module.js" }

globalThis

globalThis는 환경에 관계없이 전역객체를 통일된 방법으로 참조할 수 있는 방법이다.

// browser environment
console.log(globalThis);    // => Window {...}

// node.js environment
console.log(globalThis);    // => Object [global] {...}

// web worker environment
console.log(globalThis);    // => DedicatedWorkerGlobalScope {...}

ES2021 (ES12)

  • String.prototype.replaceAll()
  • Promise.any()
  • WeakRefs
  • Logical assignment operators (논리 할당 연산자)
  • Numeric separators (숫자 구분 기호)
  • Array.prototype.sort 개선

String.prototype.replaceAll()

정규식에 g옵션을 통해 전역으로 적용하지 않고도 문자열의 지정한 모든 문자열을 특정 문자열의 값으로 변경한다.

const str = 'hello world';
str.replaceAll('l', ''); // "heo word"

Promise.any()

Promise 반복 가능 객체를 수신하고 Promise 중 하나가 성공할 때마다 성공한 Promise를 반환한다. iterable 객체의 Promise 중 어느 것도 성공하지 못하면(즉, 모든 Promise가 실패/거부됨) 실패한 Promise가 반환된다.

const anySuccessPromises = [
	new Promise((res, rej) => setTimeout(res, 200, 'first')),
	new Promise((res, rej) => setTimeout(rej, 100, 'second')),
	new Promise((res, rej) => setTimeout(res, 300, 'third')),
];

// first
Promise.any(anySuccessPromises)
.then(value => console.log(value))
.catch(error => console.error(error));

const allFailurePromises = [
	new Promise((res, rej) => setTimeout(rej, 100, 'first')),
	new Promise((res, rej) => setTimeout(rej, 200, 'second')),
	new Promise((res, rej) => setTimeout(rej, 300, 'third')),
];

// AggregateError: All promises were rejected
Promise.any(anySuccessPromises)
.then(value => console.log(value))
.catch(error => console.error(error));

WeakRefs

WeakRef개체를 사용하면 해당 개체가 가비지 수집되는 것을 방지하지 않고 다른 개체에 대한 약한 참조를 유지할 수 있다.

class Counter {
  constructor(element) {
    // Remember a weak reference to the DOM element
    this.ref = new WeakRef(element);
    this.start();
  }

  start() {
    if (this.timer) {
      return;
    }

    this.count = 0;

    const tick = () => {
      // Get the element from the weak reference, if it still exists
      const element = this.ref.deref();
      if (element) {
        element.textContent = ++this.count;
      } else {
        // The element doesn't exist anymore
        console.log("The element is gone.");
        this.stop();
        this.ref = null;
      }
    };

    tick();
    this.timer = setInterval(tick, 1000);
  }

  stop() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = 0;
    }
  }
}

const counter = new Counter(document.getElementById("counter"));
setTimeout(() => {
  document.getElementById("counter").remove();
}, 5000);

WeakRefs와 Finalizers 위주로 정리해본 ES2021
약한 참조와 Finalizer

Logical assignment operators (논리 할당 연산자)

// before
obj.prop = obj.prop || foo(); // obj.prop이 잘못된 값일 경우 할당
obj.prop = obj.prop && foo(); // obj.prop이 올바른 값일 경우 할당
obj.prop = obj.prop ?? foo(); // obj.prop이 null이나 undefined일 경우 할당

// after
obj.prop ||= foo();
obj.prop &&= foo();
obj.prop ??= foo();

Numeric separators (숫자 구분 기호)

// before
10000000000 // 100억
// after
10_000_000_000 // 100억
console.log(10_000_000_000); // 10000000000

Array.prototype.sort 개선

sort는 implementation-defined로 기본적인 스펙만 제공하고 나머지는 브라우저에게 맡겼기 때문에 브라우저마다 구현이 달라서 정렬 결과가 다른 문제가 있었다. 이 스펙을 좀 더 정교하게 정의해서 브라우저마다 다를 수 있는 경우의 수를 줄였다.

ES2022 (ES13)

ES2022는 2022년 6월에 출시되며 2022년 3월까지 4단계에 도달한 모든 아이디어는 JavaScript에 포함될 예정이다.

  • Top-level Await Operator
  • Class Field Declarations
  • Private Methods and Fields
  • Static Class Fields and Private Static Methods
  • Regexp Match Indices
  • Ergonomic Brand Checks for Private Fields
  • at() Function for Indexing
  • Scalable Object.prototype.hasOwnProperty()
  • Temporal Function

TC39 Stage 4 / Finished

Top-level Await Operator

이전에는 비동기 함수 외부에서 await 키워드를 선언할 수 없어 오류가 발생했다. 이제 비동기 함수 및 클래스 외부에서 await 연산자를 선언하여 동기화 문제를 해결할 수 있다.

import {getUser} from "./data/User"
let user = await getUser();

Class Field Declarations

처음에는 생성자 내에서만 클래스 필드를 선언할 수 있었지만 이제는 4단계의 제안을 사용하여 생성자를 호출할 필요없이 클래스 자체에서 선언할 수 있다.

class hello {
  fields = 0;
  title;
}

Private Methods and Fields

# 기호를 접두사로 사용하여 private 클래스 필드를 직접 선언할 수 있다. 동일한 기호를 사용하여 메서드와 접근자를 비공개로 설정할 수 있으며 동시에 getter 및 setter 메서드를 사용할 수도 있다.

class hello {
  fields = 0;
  #title;
  
  get #title() { return #title; }
  set #title() { #title = null; }
}

Static Class Fields and Private Static Methods

static 키워드를 사용하여 정적 클래스 필드와 개인 정적 메서드를 선언하는 방법을 제공

class hello {
  name;
  static title = 'here';
  static get title() { return title; }
}

Regexp Match Indices

d문자를 활용하여 일치하는 문자열의 시작 및 끝 인덱스가 있는 배열을 얻을 수 있다.

const re1 = /a+(?<Z>z)?/d;

// indices are relative to start of the input string:
const s1 = "xaaaz";
const m1 = re1.exec(s1);
m1.indices[0][0] === 1;
m1.indices[0][1] === 5;
s1.slice(...m1.indices[0]) === "aaaz";

Ergonomic Brand Checks for Private Fields

in 연산자를 사용하여 특정 클래스에 필드가 있는지 여부를 간단히 확인할 수 있다.

class hello{
  name;
  #title;
    get #title() {
    return #title;
  }
  set #title() {
  	#title=null;
  }
  static hasTitle(obj1) {
    return #title in obj1;
  }
}

at() Function for Indexing

at() 함수를 사용하여 양수 및 음수 인덱스를 모두 사용하여 문자열을 인덱싱할 수 있다.

array= [1.2.4.5]
console.log(array[array.length-1]);
console.log(array.at(-1)); 

lable Object.prototype.hasOwnProperty()

Object.prototype.hasOwnProperty.call()과 동일한 hasOwn() 추가

const obj1={ hello:'Hi' }
let hasHello1=Object.prototype.hasOwnProperty.call(obj1, 'hello');
let hasHello= obj1.hasOwn(obj1, 'hello'); // 
console.log(hasHello);
console.log(hasHello1);

Temporal Function (stage 3)

Temporal은 ECMAScript 언어에 최신 날짜/시간 API를 제공하는 최상위 네임스페이스 역할을 하는 전역 개체 제공

ES2023 (ES14)

  • Find array from the last
  • Hashbang Grammer
  • Symbols as WeakMap keys
  • Change Array by Copy
    • Array.prototype.toReversed()
    • Array.prototype.toSorted(compareFn)
    • Array.prototype.toSpliced(start, deleteCount, ...items)
    • Array.prototype.with(index, value)

Find array from the last

이 함수를 사용하면 조건에 따라 배열의 마지막 요소부터 첫 번째 요소까지 찾을 수 있습니다.

const array = [{a: 1, b: 1}, {a: 2, b: 2}, {a: 3, b: 3}, {a: 4, b: 4}]

console.log(array.findLast(n => n)); //result -> {a: 4,b: 4 }

console.log(array.findLast(n => n.a * 5 === 20)); // result -> {a:4,b:4} as the condition is true so it returns the last element.

console.log(array.findLast(n => n.a * 5 === 21)); //result -> undefined as the condition is false so return undefined instead of {a:4,b:4}.

console.log(array.findLastIndex(n => n.a * 5 === 21)); // result -> -1 as the condition is not justified for returning the last element.

console.log(array.findLastIndex(n => n.a * 5 === 20)); // result -> 3 which is the index of the last element as the condition is true.

Hashbang Grammer

이 기능을 사용하면 일부 CLI에서 해시방/셰방을 사용할 수 있습니다. Shebang은 #! 로 표시되며 스크립트 시작 부분에 있는 특수 줄로, 스크립트를 실행할 때 어떤 인터프리터를 사용할지 운영 체제에 알려주는 역할을 합니다.

#!/usr/bin/env node
// in the Script Goal
'use strict';
console.log(2*3);

#!/usr/bin/env node
// in the Module Goal
export {};
console.log(2*2);

#!/usr/bin/env 노드 이 줄은 Node.js 소스 파일을 자체적으로 실행 파일로 직접 호출합니다. 노드 인터프리터를 통해 명시적으로 파일을 호출하려면 #!/usr/bin/env node가 필요하지 않습니다(예: node ./file).

Symbols as WeakMap keys

이를 통해 고유한 심볼을 키로 사용할 수 있습니다. 현재 위크맵은 객체만 키로 허용하도록 제한되어 있습니다. 객체가 위크맵의 키로 사용되는 이유는 객체와 위크맵이 동일한 아이덴티티 측면을 공유하기 때문입니다. Symbol은 ECMAScript에서 유일하게 고유한 값을 허용하는 기본 유형이므로 WeakMap으로 새 객체를 생성하는 대신 Symbol을 키로 사용할 수 있습니다.

const weak = new WeakMap();

const key = Symbol('my ref');
const someObject = { a:1 };

weak.set(key, someObject);
console.log(weak.get(key));

Change Array by Copy

원래 배열을 업데이트하는 대신 변경 사항과 함께 새 복사본을 반환하여 배열을 변경할 수 있는 추가 메서드가 Array.prototype에 제공됩니다.

Array.prototype.toReversed(), Array.prototype.toSorted(compareFn), Array.prototype.toSpliced(start, deleteCount, ...items), Array.prototype.with(index, value)

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toReversed */

const reversed = numbers.toReversed();
console.log("reversed", reversed); // "reversed", [9, 8, 7, 6, 5, 4, 3, 2, 1]
console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toSorted  */
const sortedArr = numbers.toSorted();
console.log("sorted", sortedArr); // "sorted", [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* with */
const replaceWith = numbers.with(1, 100);
console.log("with", replaceWith); // "with", [1, 100, 3, 4, 5, 6, 7, 8, 9]
console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* toSpliced */
const splicedArr = numbers.toSpliced(0, 4);
console.log("toSpliced", splicedArr); // "toSpliced", [5, 6, 7, 8, 9]
console.log("original", numbers); // "original", [1, 2, 3, 4, 5, 6, 7, 8, 9]

출처

https://velog.io/@kyusung/after-es6
https://wormwlrm.github.io/2018/10/03/What-is-the-difference-between-javascript-and-ecmascript.html
https://dev.to/jasmin/what-is-new-in-es2023-4bcm

profile
4년차 프론트엔드 개발자 장세진

0개의 댓글