メインコンテンツまでスキップ

「ES2019」タグの記事が9件件あります

全てのタグを見る

JSONをECMAScriptの部分集合として統合する(Subsume JSON a.k.a. JSON ⊂ ECMAScript)

· 約8分
Mathias Bynens ([@mathias](https://twitter.com/mathias))

JSON ⊂ ECMAScript 提案により、JSONはECMAScriptの構文的部分集合となりました。これがすでにそうでなかったことに驚いたなら、あなたは一人ではありません!

古いES2018の挙動

ES2018では、ECMAScriptの文字列リテラルにはエスケープされていないU+2028 LINE SEPARATORおよびU+2029 PARAGRAPH SEPARATOR文字を含めることができませんでした。これらはそのコンテキストでも行終端子と見なされるためです:

// 未エスケープのU+2028文字を含む文字列。
const LS = '
';
// → ES2018: SyntaxError

// `eval`によって生成された、未エスケープのU+2029文字を含む文字列:
const PS = eval('"\u2029"');
// → ES2018: SyntaxError

これは問題です。なぜなら、JSON文字列にはこれらの文字を含めることができるからです。その結果、開発者はこれらの文字を処理するために、ECMAScriptプログラム内に有効なJSONを埋め込む際に特別な後処理ロジックを実装する必要がありました。このようなロジックがなければ、コードに微妙なバグが発生したり、セキュリティ問題が生じる可能性さえありました!

安定した `Array.prototype.sort`

· 約4分
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);

`Symbol.prototype.description`

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

JavaScript の Symbol は作成時に説明を付けることができます:

const symbol = Symbol('foo');
// ^^^^^

以前は、この説明にプログラム的にアクセスする唯一の方法は Symbol.prototype.toString() を間接的に使用することでした:

const symbol = Symbol('foo');
// ^^^^^
symbol.toString();
// → 'Symbol(foo)'
// ^^^
symbol.toString().slice(7, -1); // 🤔
// → 'foo'

しかし、このコードは少し魔法のようで自明ではなく、“意図を表現し、実装を示さない”という原則に反しています。また、このテクニックでは説明がないシンボル (例: Symbol()) と、空の文字列を説明として持つシンボル (例: Symbol('')) を区別することができません。

`Object.fromEntries`

· 約5分
Mathias Bynens ([@mathias](https://twitter.com/mathias)), JavaScript ウィスパラー

Object.fromEntries は、組み込みの JavaScript ライブラリへの有益な追加機能です。その機能を説明する前に、既存の Object.entries API を理解することが助けになります。

Object.entries

Object.entries API はしばらく前から存在しています。

オブジェクト内の各キーと値のペアについて、Object.entries は配列を返します。その配列の最初の要素がキー、2番目の要素が値です。

for-of と組み合わせて使うと、Object.entries はすべてのキーと値のペアをエレガントにループ処理するための非常に便利な方法を提供します。

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 の逆の動作をします。これにより、エントリを基にオブジェクトを簡単に再構築できるようになります。

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

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

一般的な使用例として、オブジェクトの変換があります。これを行うにはエントリをループ処理し、すでにおなじみの配列メソッドを使用します。

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 }

この例では、オブジェクトを filter してキーの長さが 1 のものだけを取得します。つまり、キー xy のみで、キー abc は取得しません。その後、残りのエントリを map して、各キーと値のペアを更新して返します。この例では、各値を 2 倍にして新しい値を得ます。結果として、新しいオブジェクトが得られます。そこには xy のプロパティのみがあります。

`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.flat と呼ばれる理由で、なぜ Array.prototype.flatten ではないのかについては、こちらをお読みください: #SmooshGate の詳細を確認!

Array.prototype.flatMap

もうひとつの例を見てみます。duplicate という関数は引数に値を取り、その値を2回含む配列を返します。この関数を配列のそれぞれの値に適用すると、ネストされた配列が得られます。

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} のサポート

適切に形成された`JSON.stringify`

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

JSON.stringifyは以前、入力に孤立したサロゲートペアが含まれている場合、不正な形式のUnicode文字列を返す仕様でした:

JSON.stringify('\uD800');
// → '"�"'

「適切に形成されたJSON.stringify」提案では、JSON.stringifyが孤立したサロゲートペアに対してエスケープシーケンスを出力するように変更され、その出力は有効なUnicode(UTF-8で表現可能)となります:

オプションの`catch`バインディング

· 約1分
Mathias Bynens ([@mathias](https://twitter.com/mathias))

try文のcatch句は以前はバインディングが必要でした:

try {
doSomethingThatMightThrow();
} catch (exception) {
// ^^^^^^^^^
// バインディング名を付ける必要があります、たとえそれを使用しなくても!
handleException();
}

ES2019では、catchバインディングなしで使用可能になりました。この機能は、例外を処理するコードでexceptionオブジェクトが必要ない場合に便利です。

try {
doSomethingThatMightThrow();
} catch { // → バインディングなし!
handleException();
}

オプションのcatchバインディング対応状況

`String.prototype.trimStart`と`String.prototype.trimEnd`

· 約1分
Mathias Bynens ([@mathias](https://twitter.com/mathias))

ES2019はString.prototype.trimStart()String.prototype.trimEnd()を導入しました。

const string = '  hello world  ';
string.trimStart();
// → 'hello world '
string.trimEnd();
// → ' hello world'
string.trim(); // ES5
// → 'hello world'

この機能は以前は標準ではないtrimLeft()trimRight()メソッドを通じて利用可能でしたが、互換性のために新しいメソッドのエイリアスとして残っています。

const string = '  hello world  ';
string.trimStart();
// → 'hello world '
string.trimLeft();
// → 'hello world '
string.trimEnd();
// → ' hello world'
string.trimRight();
// → ' hello world'
string.trim(); // ES5
// → 'hello world'