본문으로 건너뛰기

"io19" 태그로 연결된 13개 게시물개의 게시물이 있습니다.

모든 태그 보기

`Intl.NumberFormat`

· 약 4분
Mathias Bynens ([@mathias](https://twitter.com/mathias)) 그리고 Shane F. Carr

현재 Intl.NumberFormat API에 대해 알고 있을 수도 있습니다. 이 API는 현대 환경에서 이미 오랫동안 지원되고 있습니다.

Intl.NumberFormat의 기본 형태는 지역별 숫자 형식을 지원하는 재사용 가능한 포매터 인스턴스를 생성할 수 있도록 합니다. 다른 Intl.*Format API처럼, 포매터 인스턴스는 formatformatToParts 메서드 모두를 지원합니다:

`globalThis`

· 약 2분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

웹 브라우저에서 사용하기 위한 JavaScript를 작성한 적이 있다면, 전역 this에 접근하기 위해 window를 사용한 적이 있을 것입니다. Node.js에서는 global을 사용했을지도 모릅니다. 두 환경에서 모두 작동해야 하는 코드를 작성한 경우, 사용할 수 있는 것을 감지하여 이를 사용했을 것입니다. 그러나 지원하려는 환경과 사용 사례가 늘어남에 따라 체크해야 할 식별자의 목록이 증가하면서 금방 복잡해집니다:

약한 참조와 파이널라이저

· 약 8분
사티야 구나세카란 ([@_gsathya](https://twitter.com/_gsathya)), 마티아스 바이넨스 ([@mathias](https://twitter.com/mathias)), 슈유 꿔 ([@_shu](https://twitter.com/_shu)), 레셰크 스비르스키 ([@leszekswirski](https://twitter.com/leszekswirski))

일반적으로 자바스크립트에서 객체에 대한 참조는 _강하게 유지_됩니다. 즉, 객체를 참조하고 있는 동안에는 가비지 컬렉션이 이루어지지 않습니다.

const ref = { x: 42, y: 51 };
// `ref`(혹은 같은 객체에 대한 다른 참조)를 갖고 있는 한,
// 객체는 가비지 컬렉션되지 않습니다.

현재로서는 WeakMapWeakSet만이 자바스크립트에서 약하게 객체를 참조하는 유일한 방법입니다. WeakMap이나 WeakSet에 객체를 추가해도 가비지 컬렉션을 막을 수는 없습니다.

const wm = new WeakMap();
{
const ref = {};
const metaData = 'foo';
wm.set(ref, metaData);
wm.get(ref);
// → metaData
}
// 이제 이 블록 스코프 내에서 `ref`에 대한 참조를 갖고 있지 않기 때문에,
// `wm`의 키임에도 불구하고 가비지 컬렉션이 가능합니다.

안정적인 `Array.prototype.sort`

· 약 3분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

강아지 배열이 있다고 가정합시다. 각 강아지는 이름과 등급을 가지고 있습니다. (이것이 이상한 예제처럼 느껴진다면, 정확히 이런 내용을 전문으로 하는 Twitter 계정이 있다는 것을 알아두세요... 묻지 마세요!)

// 배열이 `name` 기준으로 알파벳 순서로 미리 정렬되어 있는 것을 확인하세요.
const doggos = [
{ name: 'Abby', rating: 12 },
{ name: 'Bandit', rating: 13 },
{ name: 'Choco', rating: 14 },
{ name: 'Daisy', rating: 12 },
{ name: 'Elmo', rating: 12 },
{ name: 'Falco', rating: 13 },
{ name: 'Ghost', rating: 14 },
];
// 강아지를 내림차순으로 `rating` 기준으로 정렬합니다.
// (이 작업은 `doggos`를 제자리에서 업데이트합니다.)
doggos.sort((a, b) => b.rating - a.rating);

`Object.fromEntries`

· 약 3분
Mathias Bynens ([@mathias](https://twitter.com/mathias)), JavaScript 전문가

Object.fromEntries는 자바스크립트 내장 라이브러리에 유용한 추가 기능입니다. 무엇을 하는지 설명하기 전에 기존의 Object.entries API를 이해하는 것이 도움이 됩니다.

Object.entries

Object.entries API는 이미 오래전부터 존재해 왔습니다.

객체의 각 키-값 쌍에 대해 Object.entries는 첫 번째 요소가 키이고 두 번째 요소가 값인 배열을 제공합니다.

Object.entries는 특히 for-of와 결합할 때 유용하며, 객체의 모든 키-값 쌍을 우아하게 순회할 수 있게 합니다:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

for (const [key, value] of entries) {
console.log(`The value of ${key} is ${value}.`);
}
// 출력:
// The value of x is 42.
// The value of y is 50.

불행히도, 현재까지는 entries 결과를 동일한 객체로 되돌리는 간단한 방법이 없었습니다… 이제는 가능합니다!

Object.fromEntries

새로운 Object.fromEntries API는 Object.entries의 반대 동작을 수행합니다. 이를 통해 entries를 기반으로 객체를 손쉽게 다시 구성할 수 있습니다:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

const result = Object.fromEntries(entries);
// → { x: 42, y: 50 }

일반적인 사용 사례 중 하나는 객체를 변환하는 것입니다. 이제 entries를 순회하고 이미 익숙한 배열 메서드를 사용하여 수행할 수 있습니다:

const object = { x: 42, y: 50, abc: 9001 };
const result = Object.fromEntries(
Object.entries(object)
.filter(([ key, value ]) => key.length === 1)
.map(([ key, value ]) => [ key, value * 2 ])
);
// → { x: 84, y: 100 }

이 예제에서는 길이가 1인 키만 가져오도록 객체를 filter합니다. 즉, 키 xy는 포함하고, 키 abc는 포함하지 않습니다. 그런 다음 남아있는 entries를 map으로 순회하여 각 키-값 쌍에 대한 업데이트된 쌍을 반환합니다. 이 예제에서는 각 값을 2로 곱하여 두 배로 만듭니다. 최종 결과는 xy 속성만 가지며 새 값이 있는 새 객체입니다.

Promise 조합자들

· 약 4분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

ES2015에서 Promise가 도입된 이후, 자바스크립트는 정확히 두 가지 Promise 조합자: Promise.allPromise.race를 지원했습니다.

현재 두 가지 새로운 제안인 Promise.allSettledPromise.any가 표준화 과정을 진행 중입니다. 이 추가들로 인해 자바스크립트에는 총 네 가지 Promise 조합자가 존재하게 되며, 각각 다른 사용 사례를 가능하게 합니다.

Array.prototype.flat`과 `Array.prototype.flatMap`

· 약 2분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Array.prototype.flat

이 예제의 배열은 여러 수준으로 중첩되어 있습니다. 배열 안에 또 다른 배열이 포함됩니다.

const array = [1, [2, [3]]];
// ^^^^^^^^^^^^^ 외부 배열
// ^^^^^^^^ 내부 배열
// ^^^ 가장 안쪽 배열

Array#flat은 주어진 배열의 평탄화된 버전을 반환합니다.

array.flat();
// → [1, 2, [3]]

// …다음과 동등합니다:
array.flat(1);
// → [1, 2, [3]]

기본 깊이는 1이지만, 원하는 깊이까지 재귀적으로 평탄화를 실행하려면 숫자를 전달할 수 있습니다. 배열에 더 이상 중첩 배열이 없을 때까지 평탄화를 계속하려면 Infinity를 전달합니다.

// 배열에 더 이상 중첩된 배열이 포함되지 않을 때까지 재귀적으로 평탄화:
array.flat(Infinity);
// → [1, 2, 3]

왜 이 메서드를 Array.prototype.flatten이 아니라 Array.prototype.flat으로 명명했는지 궁금하신가요? #SmooshGate에 대한 우리의 설명을 읽어보세요!

Array.prototype.flatMap

다음은 또 다른 예제입니다. 값 하나를 두 번 포함하는 배열을 반환하는 duplicate 함수를 정의합니다. 이 배열의 각 값에 duplicate를 적용하면 중첩된 배열이 생성됩니다.

const duplicate = (x) => [x, x];

[2, 3, 4].map(duplicate);
// → [[2, 2], [3, 3], [4, 4]]

그런 다음 결과에 flat을 호출하여 배열을 평탄화할 수 있습니다:

[2, 3, 4].map(duplicate).flat(); // 🐌
// → [2, 2, 3, 3, 4, 4]

이 패턴이 함수형 프로그래밍에서 매우 일반적이기 때문에, 이를 위한 전용 flatMap 메서드가 새로 추가되었습니다.

[2, 3, 4].flatMap(duplicate); // 🚀
// → [2, 2, 3, 3, 4, 4]

flatMapmap을 먼저 수행하고 flat을 별도로 수행하는 것보다 조금 더 효율적입니다.

flatMap의 사용 사례에 관심 있으신가요? Axel Rauschmayer의 설명을 확인하세요.

Array#{flat,flatMap} 지원

숫자 구분자

· 약 2분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

큰 숫자 리터럴은 특히 반복되는 숫자가 많을 때, 인간의 눈으로 빠르게 해석하기 어렵습니다:

1000000000000
1019436871.42

가독성을 개선하기 위해 새로운 JavaScript 언어 기능은 숫자 리터럴에서 언더스코어를 구분 기호로 사용할 수 있게 합니다. 따라서 위의 코드는 이제 숫자를 천 단위로 그룹화하여 다시 작성할 수 있습니다:

`String.prototype.matchAll`

· 약 2분
Mathias Bynens ([@mathias](https://twitter.com/mathias))

문자열에서 동일한 정규식을 반복 적용하여 모든 매치를 찾는 것은 일반적인 경우입니다. 어느 정도는 String#match 메서드를 사용하여 오늘날에도 가능합니다.

이 예제에서, 우리는 16진수 숫자로만 구성된 모든 단어를 찾고 각 매치를 로그로 출력합니다:

const string = 'Magic hex numbers: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.match(regex)) {
console.log(match);
}

// 출력:
//
// 'DEADBEEF'
// 'CAFE'

그러나 이것은 매치된 _서브스트링_만 제공합니다. 일반적으로 여러분은 서브스트링뿐만 아니라 각 서브스트링의 인덱스 또는 각 매치 내의 캡처 그룹과 같은 추가 정보를 원합니다.

자체 반복문을 작성하고 매치 객체를 스스로 추적함으로써 이를 달성할 수 있습니다. 그러나 이것은 다소 번거롭고 그렇게 편리하지 않습니다:

const string = 'Magic hex numbers: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
let match;
while (match = regex.exec(string)) {
console.log(match);
}

// 출력:
//
// [ 'DEADBEEF', index: 19, input: 'Magic hex numbers: DEADBEEF CAFE' ]
// [ 'CAFE', index: 28, input: 'Magic hex numbers: DEADBEEF CAFE' ]

새로운 String#matchAll API를 사용하면 이전보다 더 쉽게 매치 객체를 얻을 수 있습니다. 이제 간단한 for-of 루프를 작성하여 모든 매치 객체를 가져올 수 있습니다.

const string = 'Magic hex numbers: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.matchAll(regex)) {
console.log(match);
}

// 출력:
//
// [ 'DEADBEEF', index: 19, input: 'Magic hex numbers: DEADBEEF CAFE' ]
// [ 'CAFE', index: 28, input: 'Magic hex numbers: DEADBEEF CAFE' ]

String#matchAll은 캡처 그룹이 포함된 정규식에서 특히 유용합니다. 이는 각 개별 매치에 대한 캡처 그룹 포함 정보를 제공합니다.

const string = 'Favorite GitHub repos: tc39/ecma262 v8/v8.dev';
const regex = /\b(?<owner>[a-z0-9]+)\/(?<repo>[a-z0-9\.]+)\b/g;
for (const match of string.matchAll(regex)) {
console.log(`${match[0]} at ${match.index} with '${match.input}'`);
console.log(`→ owner: ${match.groups.owner}`);
console.log(`→ repo: ${match.groups.repo}`);
}

`Intl.ListFormat`

· 약 3분
Mathias Bynens ([@mathias](https://twitter.com/mathias)) 및 Frank Yung-Fong Tang

모던 웹 애플리케이션은 종종 동적 데이터로 구성된 목록을 사용합니다. 예를 들어, 사진 뷰어 앱은 다음과 같은 내용을 표시할 수 있습니다:

이 사진에는 Ada, Edith, 그리고 Grace가 포함되어 있습니다.

텍스트 기반 게임은 다른 종류의 목록을 가질 수 있습니다:

초능력을 선택하세요: 투명화, 염력, 또는 공감 능력.

각 언어에는 다른 목록 포맷팅 규칙과 단어가 있기 때문에 로컬화된 목록 포맷터를 구현하는 것은 간단하지 않습니다. 지원하고자 하는 각 언어에 대해 모든 단어(위 예에서는 '그리고' 또는 '혹은'과 같은 단어)를 목록화해야 할 뿐만 아니라, 이러한 언어들의 정확한 포맷팅 규칙을 인코딩해야 합니다! Unicode CLDR은 이러한 데이터를 제공하지만 이를 JavaScript에서 사용하려면 다른 라이브러리 코드와 함께 임베드되어 제공되어야 합니다. 이는 불행히도 이러한 라이브러리의 번들 크기를 증가시켜 로드 시간, 파싱/컴파일 비용, 메모리 소비에 부정적인 영향을 미칩니다.