- Optional
catchbinding - JSON superset
Symbol.prototype.descriptionFunction.prototype.toStringrevisionObject.fromEntries- Well-formed
JSON.stringify String.prototype.{trimStart,trimEnd}Array.prototype.{flat,flatMap}
try {
throw new Error("Whoops!");
} catch (unused) {}catch 블록에서 종종 Catch Parameter를 사용하지 않을 때가 있어요. 이런 경우, 편의를 위해 Catch Parameter를 생략할 수 있도록 변경되었어요.
try {
throw new Error("Whoops!");
} catch {}이는 기존 코드와의 호환성을 해치지 않아요.
참고: Github - proposal-optional-catch-binding, tc39 - Optional catch binding
ECMAScript는 JSON을 JSON.parse의 subset(부분집합)으로 주장하고 있었지만, 실제로는 JSON에서 지원하는 모든 유니코드 이스케이프 시퀀스를 지원하지 않았어요.
const LS = "\u2028"; // Line separator
const PS = "\u2029"; // Paragraph separator
JSON.parse(`{"lineSeparator":"${LS}"}`); // SyntaxError
JSON.parse(`{"paragraphSeparator":"${PS}"}`); // SyntaxError예를 들어, 위 코드에서는 JSON에서 지원하는 유니코드 이스케이프 시퀀스인 Line separator(\u2028)와 Paragraph separator(\u2029)를 사용했지만, ECMAScript에서는 SyntaxError가 발생해요.
따라서 ECMAScript의 구문을 JSON의 상위집합(Superset)으로 확장하기 위해, 위와 같은 두 개의 유니코드 이스케이프 시퀀스를 지원하게 됐어요.
const sym = Symbol("foo");
console.log(sym); // Symbol(foo)
console.log(sym.description); // foo심볼(Symbol)을 생성할 때 선택적으로 설명(description)을 정의할 수 있어요. 기존에는 Symbol.prototype.toString을 통해 설명을 추출했지만, 설명만 추출하려면 추가적인 처리가 필요했어요. 이제 Symbol.prototype.description을 통해 명시적으로 설명을 추출할 수 있어요.
예를 들어 Symbol("foo").toString().slice(7, -1); // foo 와 같은 방법으로 설명을 추출할 수 있었어요. 하지만 이제는 Symbol("foo").description; // foo 와 같이 명시적으로 설명을 추출할 수 있어요.
참고: Github - proposal-Symbol-description, MDN - Symbol.prototype.description
해당 제안은 전방 호환성(Future-compatibility)가 없는 요구사항을 제거하고, 반환값을 명시적으로 정의하는 것을 목표로 해요.
이전에는 toString 메서드가 구조적으로 유효한 ECMAScript를 반환하지 못했다면, eval 함수를 통해 해당 문자열을 실행하면 SyntaxError가 발생해야 한다는 요구사항이 있었어요. 이러한 요구사항은 전방 호환성을 제공하지 못하기 때문에, 해당 요구사항은 제거되었고 [native code]와 같은 문자열을 반환하는 것으로 대체되었어요.
- 바운드된 익명 함수이거나 내장 함수인 경우, 함수 바디에
[native code]를 넣어 반환 a. 익명 함수가 아닌 경우, 잘 알려진 내장 객체(Well-known intrinsic object;Array.prototype.push)인 경우, 함수 이름을 함께 반환 - 함수 내부에
[[SourceText]]내부 슬롯이 있는 경우, 해당 속성을 반환 - 호출 가능한 객체인 경우, NativeFunction 형태 즉, 바디에
[native code]를 넣어 반환
예외 상황에는 TypeError를 던지도록 명시되어 있어요.
// 바운드된 익명 함수
(() => {}).bind({}).toString(); // "() => { [native code] }"
// 내장 함수
Array.prototype.push.toString(); // "function push() { [native code] }"
// 함수 내부에 [[SourceText]] 내부 슬롯이 있는 경우
(function foo() {
console.log("foo");
}).toString(); // 'function foo() {\n console.log("foo");\n}'
// arrow function
(() => {}).toString(); // "() => {}"
// generator function
(function* () {}).toString(); // "function*() {}"
// async function
(async function () {}).toString(); // "async function() {}"obj = Object.fromEntries([
["foo", "bar"],
["baz", 42],
]); // { foo: "bar", baz: 42 }Object.fromEntries 메서드는 배열을 객체로 변환하는 메서드예요. 이는 Object.entries 메서드의 반대 역할을 해요. 이전에는 배열을 객체로 변환하려면 복잡한 방법이 필요했지만, 이제 간단히 처리할 수 있어요.
const map = new Map([
["foo", "bar"],
["baz", 42],
]);
JSON.stringify(map); // "{}"
JSON.stringify(Object.fromEntries(map)); // {"foo":"bar","baz":42}Map 객체는 JSON.stringify 메서드를 통해 직렬화할 수 없어요. 하지만 Object.fromEntries 메서드를 통해 Map 객체를 객체로 변환함으로써 직렬화할 수 있어요.
참고: Github - proposal-object-from-entries,MDN - Object.fromEntries
RFC 8529 섹션 8.1에 따르면, JSON 문자열은 UTF-8 인코딩을 사용해야 한다고 명시되어 있어요. 하지만 이전의 JSON.stringify 메서드는 UTF-8로 표현할 수 없는 코드 포인트를 포함하는 문자열을 반환할 수 있었어요.
JSON.stringify("\uD800"); // '"�"'특히, 위와 같은 surrogate 코드 포인트(U+D800 ~ U+DFFF)를 포함했어요.
JSON.stringify("\uD800"); // '"\\ud800"'이러한 문제를 해결하기 위해 짝이 맞지 않는 surrogate 코드 포인트를 포함하는 문자열을 반환하지 않는 대신, JSON 이스케이프 시퀀스로 표현하게 됐어요
ECMAScript 2016에서 String.prototype.trim만 표준화 했지만, String.prototype.{trimLeft,trimRight}는 표준화하지 않았어요.
이를 표준화 했는데, padStart와 padEnd 메서드와 일관성을 유지하기 위해 String.prototype.trimStart와 String.prototype.trimEnd로 메서드를 표준화하게 됐어요.
String.prototype.trimStart === String.prototype.trimLeft; // true
String.prototype.trimEnd === String.prototype.trimRight; // true하지만 웹 호환성을 위해 String.prototype.{trimLeft,trimRight}을 두 메서드의 별칭으로 유지하게 됐어요.
[1, 2, [3, 4]].flat(); // [1, 2, 3, 4]
[1, 2, [3, [4]]].flat(2); // [1, 2, 3, 4]Array.prototype.flat 메서드는 중첩된 배열을 평탄화(flatten)하는 메서드이에요. 이 메서드는 기본적으로 1단계의 중첩 배열만 평탄화하며, 인수를 통해 평탄화할 깊이를 지정할 수 있어요.
[1, 2, 3].flatMap((x) => [x, x * 2]); // [1, 2, 2, 4, 3, 6]
[1, 2, 3].map((x) => [x, x * 2]).flat(); // [1, 2, 2, 4, 3, 6]Array.prototype.flatMap 메서드는 map 메서드를 수행한 후 flat 메서드를 수행하는 메서드이에요. 즉, map 메서드와 flat 메서드를 한 번에 더 효율적으로 수행할 수 있어요.
참고: Github - proposal-flatMap, MDN - Array.prototype.flat, MDN - Array.prototype.flatMap