Language/Javascript

Javascript - ECMAScript 2023(ES14)에 추가된 기능

둉이 2023. 6. 5. 19:22

 

올해 2023년 6월부터 추가된 ES14의 여러 기능들에 대해 알아봅시다.

 

자세한 내용은 아래 홈페이지에서 확인 가능합니다.

 

ECMAScript® 2023 Language Specification

The first and subsequent editions of ECMAScript have provided, for certain operators, implicit numeric conversions that could lose precision or truncate. These legacy implicit conversions are maintained for backward compatibility, but not provided for BigI

tc39.es

 

 

배열 관련 메소드

map, filter 등의 메소드들과는 달리, find, splice, sort 등의 배열 메소드들은 기존 배열의 값을 변경하고 변경된 배열의 참조값을 반환합니다.

 

만약 원본 배열을 변경하면 안되는 경우에 사용하게 된다면, 예상과는 다르게 코드가 동작할 수 있기 때문에 사용하기 전에 어떤 메소드가 원본 배열을 변경하는지 숙지해야 합니다.

 

이번에 추가된 배열 메소드들은 모두 원본 배열을 변경하는 기존 메소드들의 단점을 보완하기 위한 것들로, 메소드를 호출해도 원본을 변경하지 않고 복사된 배열을 변경하여 반환합니다.

 

 

findLast(func) / findLastIndex(func)

find / findIndex 메소드는 배열에서 값이나 해당 값의 인덱스를 얻을 때 주로 사용합니다.

 

기본적으로 정방향으로 탐색하기 때문에 아래처럼 배열의 뒤에 찾는 요소가 있는 경우에는 탐색 시간이 오래 걸립니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const coffeeIndex = arr.findIndex(val => val === 'coffee');

console.log(coffeeIndex);  // 5

 

이번에 추가된 findLast / findLastIndex 메소드를 사용하면 역방향으로 요소를 탐색하기 때문에 위 케이스 같은 경우에 효과적으로 사용할 수 있습니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const coffeeIndex = arr.findLastIndex(val => val === 'coffee');

console.log(coffeeIndex);  // 5

 

 

toReversed() / toSorted() / toSpliced(index, count)

reverse() 메소드는 원본 배열을 변경하기 때문에 원본 배열을 건드리지 않아야 하는 경우에는 배열을 복사해서 사용해야 한다는 불편이 있습니다.

 

이번에 추가된 toReserved 메소드는 원본 배열을 변경하지 않고 배열을 뒤집을 수 있어 이러한 불편을 개선할 수 있습니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const reversedArr = arr.toReversed();

console.log(reversedArr);  // ['coffee', 'mango', 'apple', 'dol', 'bom', 'mjkim']

 

 

toSorted 메소드도 마찬가지입니다.

 

해당 메소드를 사용하여 원본 배열을 변경하면서 정렬하는 sort() 메소드 대신 원본 배열을 변경하지 않고 정렬이 가능합니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const sortedArr = arr.toSorted();

console.log(sortedArr);  // ['apple', 'bom', 'coffee', 'dol', 'mango', 'mjkim']

 

 

toSpliced도 위와 동일합니다.

 

toSpliced()를 사용하면 기존 원본 배열을 변경하면서 요소를 삭제하는 splice() 메소드 대신 원본 배열을 변경하지 않고 요소가 삭제된 복사된 배열을 얻을 수 있습니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const deletedArr = arr.toSpliced(2, 2);  // 인덱스 2부터 2개의 요소 삭제

console.log(deletedArr);  // ['mjkim', 'bom', 'mango', 'coffee']

 

 

with(index, value)

배열의 특정 인덱스 요소를 수정해야 한다면, 다음과 같이 인덱스로 해당 배열에 접근하여 = 연산자로 새로운 값을 할당하는 방법을 사용합니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
arr[0] = 'mijeonkim';  // 원본 배열에서 0번째 인덱스 요소 값 변경
console.log(arr);  // ['mijeonkim', 'bom', 'dol', 'apple', 'mango', 'coffee']

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const copiedArr = Array.from(arr);  // 배열 복사
copiedArr[0] = 'mijeonkim';  // 복사된 배열에서 0번째 인덱스 요소 값 변경
console.log(arr);  // ['mijeonkim', 'bom', 'dol', 'apple', 'mango', 'coffee']

 

만약 기존 배열을 변경하지 않고 복사된 배열에서 특정 요소를 변경하려면 Array.from() 혹은 전개 연산자 ...를 사용하여 배열을 복사한 후 값을 변경해야 합니다.

 

with 메소드를 사용하면 번거롭게 배열을 복사한 후 수정할 필요 없이, 복사 + 수정된 배열을 얻을 수 있습니다.

const arr = ['mjkim', 'bom', 'dol', 'apple', 'mango', 'coffee'];
const editedArr = arr.with(0, 'mijeonkim');
console.log(editedArr);  // ['mijeonkim', 'bom', 'dol', 'apple', 'mango', 'coffee']

 

 

 

그 외

WeakMap의 키로 Symbol 사용

Symbol은 유일성을 보장할 수 있는 자료형으로, 주로 객체의 key에 사용됩니다.

const id1 = Symbol('id');
const id2 = Symbol('id');

console.log(id1 === id2);  // false

 

WeakMap은 Map과 함께 ES6에서 추가된 자료형입니다.

 

Map과는 달리 key로 오직 객체(object)만 사용이 가능했지만, 이제 Symbol도 WeakMap의 key로 사용할 수 있습니다.

const id1 = Symbol('id');
const id2 = Symbol('id');

const weak = new WeakMap();
weak.set(id1, '이거 좋군요');
console.log(weak.get(id1), weak.get(id2));  // 이거 좋군요 undefined

 

다만, 전역 심볼 레지스트리에 등록된 Symbol은 WeakMap의 key로 사용할 수 없습니다.

 

전역 심볼은 일반 심볼과는 달리 Symbol.for() 함수를 호출하여 생성합니다.

 

인자로 전달한 문자열로 생성된 심볼이 이미 전역 심볼 레지스트리에 존재하는 경우에는 해당 심볼을 반환하고, 없는 경우에는 생성 후 반환합니다.

 

따라서 Symbol() 함수로 생성된 심볼과는 달리 아래 코드를 실행해도 동일한 심볼이라는 결과가 나옵니다.

const id1 = Symbol.for('id');
const id2 = Symbol.for('id');

console.log(id1 === id2);  // true

 

 

참고로 Map와 WeakMap의 차이점은 다음과 같습니다.

  Map WeakMap
key 객체를 포함한 원시값 모두 사용 가능
→ string, number, object, boolean, null, undefined, symbol
null을 제외한 객체, 전역 레지스트리에 등록되지 않은 심볼만 사용 가능
메소드 size / keys() 메소드 사용 가능 size / keys()메소드 사용 불가
GC
(가비지 컬렉터)
key로 사용한 객체가 GC에 의해 사라져도 여전히 Map의 key의 객체는 존재 → value 접근 가능 key로 사용한 객체가 GC에 의해 사라지면 WeakMap의 key도 함께 사라져서 value에 접근 불가

 

 

해시뱅(Hashbang) 문법

셔뱅(Shebang)이라고도 불리는 해시뱅 문법은 스크립트 상단에 작성하는 실행될 프로그램의 인터프리터를 정의하는 코드로, 주로 UNIX 계열 OS에서 사용됩니다.

#! /usr/bin/env node

const str = 'Hello World';
console.log(str);

 

위 예시처럼 자바스크립트 파일의 첫 라인이 #!로 시작될 경우, 해당 라인을 무시합니다.