Categories: ECMAScript

ざっくり ECMAScript 2019

ざっくりと ES2019 のおさらいをしたい人向け。オカタい説明は mdn さんあたりにおまかせするとして、ゆるっとざっくり気楽にサクッとおさらい。ES2019 は try-catch 構文の仕様変更、String.prototype.trimStart、String.prototype.trimEnd、Array.prototype.flat、Array.prototype.flatMapが追加されたよ

環境構築

  • MacOS High Sierra
  • ふる〜い MBP 使ってます
  • nvm, ndenv, nodebrew のどれでもいいので node が動く環境を用意
  • VSCode 使ってます。拡張はお好みで。
  • node.js のバージョンは v14.7.0
  • 適当なディレクトリを掘って、index.js を用意しています (ファイル名はお好みで)
  • 動作確認は $ node index.js って叩いてます

最小限で動かすだけならこれだけでおっけいです。ここらへんの準備も面倒ならば codepen だの JSFiddle だの REPL だのを使ってもおk

es2019

es2019 は以下のような機能が追加されている:原文(参考 github tc39/proposals finished-proposals

Optional “catch” bindingJSON supersetSymbol.prototype.descriptionFunction.prototype.toString revisionObject.fromEntriesWell-formed JSON.stringifyString.prototype.{trimStart,trimEnd}Array.prototype.{flat,flatMap}

Optional catch binding(”try-catch” syntax changes)

try-catch 構文変更として、以下のようにキャッチバインディングとその周辺の括弧を省略することができるようになったよ

const returnExeption = () => { throw new Error("hoge") }

try{
    returnExeption()
}catch{
    console.log("error")
}

JSON superset (github 原文ママ)

JSON構文はECMA-404で定義され、RFC 7159で恒久的に固定されていますが、ECMA-262のDoubleStringCharacterとSingleStringCharacterの生成物は、エスケープされていないU+2028 LINE SEPARATORとU+2029 PARAGRAPH SEPARATOR文字を許可するように拡張することができます。

以下のコードはエラーにならなくなった。

const PS = eval("'\u2029'");
const LS = eval("'\u2028'");

Symbol.prototype.description

Symbol の説明を Symbol.prototype.toString を通してではなく、直接 desription でアクセスできるよ

const s = Symbol("Hey")
console.log(s.toString())

console.log(s.description)

// Symbol(Hey)
// Hey

Function.prototype.toString revision

とりあえず原文

The original goals of this proposal were

  • remove the forward-incompatible requirement
    If the implementation cannot produce a source code string that meets these criteria then it must return a string for which eval will throw a SyntaxError exception.
  • clarify the “functionally equivalent” requirement
  • standardise the string representation of built-in functions and host objects
  • clarify requirement of representation based on the “actual characteristics” of an object

 

The goals were later revised to include

  • ensure that the string’s parse contains the same function body and parameter list as the original

 

The goals were revised again to include

  • for functions defined using ECMAScript code, toString must return source text slice from beginning of first token to end of last token matched by the appropriate grammar production
  • for built-in function objects and bound function exotic objects, toString must not return anything other than NativeFunction
  • for callable objects which were not defined using ECMAScript code, toString must return NativeFunction
  • for functions created dynamically (through the Function and GeneratorFunction constructors), toString must synthesise a source text
  • for all other objects, toString must throw a TypeError exception

 

The goals were revised yet again to include

  • implementations must not be required to retain source text for all functions defined using ECMAScript code

翻訳

この提案の本来の目的は

  • 前方互換性のない要件を削除する
    実装がこれらの基準を満たすソースコード文字列を生成できない場合は、eval が SyntaxError 例外を投げるような文字列を返さなければなりません。
  • 「関数的に等価」という要件を明確にしました。
  • 組み込み関数とホストオブジェクトの文字列表現を標準化します。
  • オブジェクトの「実際の特性」に基づく表現の要件を明確にする

 

目標はその後、以下のように修正されました

  • 文字列のパースでは、元の文字列と同じ関数本体とパラメータリストが含まれていることを確認します。

 

目標は以下のように再改定されました。

  • ECMAScript コードを使用して定義された関数の場合、toString は、最初のトークンの先頭から最後のトークンの末尾までの、適切な文法プロダクションにマッチするソーステキストのスライスを返さなければなりません。
  • 組み込みの関数オブジェクトとバインドされた関数のエキゾチックオブジェクトの場合、toStringはNativeFunction以外のものを返してはいけません。
  • ECMAScript コードで定義されていない呼び出し可能なオブジェクトの場合、toString は NativeFunction を返さなければなりません。
  • 動的に作成された関数 (Function および GeneratorFunction コンストラクタを介して) の場合、toString はソーステキストを合成しなければなりません。
  • 他のすべてのオブジェクトの場合、toString は TypeError 例外をスローしなければなりません。

 

といった目標を改めて修正しました。

  • ECMAScript コードを使用して定義されたすべての関数のソーステキストを保持する必要はありません。

めっちゃわかりにくいし、タイトル通りなんだけど要するに「関数オブジェクトに対して toString() を実行した時の挙動を定義」したっぽい。詳しくはこっちを見て。

Object.fromEntries

Object.fromEntriesは、反復可能なキーと値のペアを受け取り、それらのペアによってキーとそれに対応する値が与えられた新しいオブジェクトを返します(意訳)

次のコードでは、配列に [ key, value ] を想定する配列を引数として渡した例です。

const obj = Object.fromEntries([['a', 0], ['b', 1]]); // { a: 0, b: 1 }
console.log(obj)

// { a: 0, b: 1 }

Well-formed JSON.stringify

乱暴な説明で申し訳ないけど、JSON.stringify が不正な Unicode 文字(列)を返さないようになったよ。JIS第3水準、JIS第4水準の漢字と戦っている人とかUnicode周りで頑張っている方には朗報?(笑)

前々までは文字化けっぽくなってたのが、ちゃんとエスケープされたりするんだけど、Wordpress もろもろ弾かれちゃうので実際に実行してみて。

// Non-BMP characters still serialize to surrogate pairs.
console.log(JSON.stringify('\uD834\uDF06'))
console.log(JSON.stringify('\uD842\uDFB7'))

もっと深く突っ込みたい人向けの検索ワード

String.prototype.{trimStart,trimEnd}

先頭、もしくは末尾の空白を取り除くことができるメソッドが追加。

// 前後3つのスペース
const str = '   content   '
console.log(str.trimStart())
console.log(str.trimStart().length)

// "content   "
// 10

console.log(str.trimEnd())
console.log(str.trimEnd().length)

// "   content"
// 10

Array.prototype.{flat,flatMap}

配列 や Map をフラットにすることができるメソッドが追加されたよ

Array.prototype.flat

フラットにするのは、ネストしている配列の1階層分。ネストされたものまでは及ばない。

const arr1 = [1, 2, [3, 4]]
const arr2 = [1, 2, [3, [4, 5]]]

console.log(arr1.flat())
console.log(arr2.flat())
console.log(arr2.flat().flat())

// [ 1, 2, 3, 4 ]
// [ 1, 2, 3, [ 4, 5 ] ]
// [ 1, 2, 3, 4, 5 ]

Array.prototype.flatMap

flatMap は、一度マッピングした後にフラットにするよ。

const arr = [1, 2, 3, 4, 5]
const users = [
    {
        name: 'taro',
        age: 20
    },
    {
        name: 'jiro',
        age: 18
    },
    {
        name: 'subro',
        age: 17
    }
]

console.log(arr.flatMap( v => v * 2))
console.log(users.flatMap( v => v.name ))

// [ 2, 4, 6, 8, 10 ]
// [ 'taro', 'jiro', 'subro' ]

 

chrowa3

Share
Published by
chrowa3

Recent Posts

ざっくり ECMAScript 2020

ざっくりと ES2020 のお…

3年 ago

ざっくり ECMAScript 2018

ざっくりと ES2018 のお…

3年 ago

ざっくり ECMAScript 2017

ざっくりと ES2017 のお…

3年 ago

ざっくり ECMAScript 2016

ざっくりと ES2016 のお…

3年 ago

ざっくり ECMAScript 2015

ざっくりと ES2015 のお…

3年 ago

Vue CLI で Pug を使う 2019年6月

Vue CLI でサクッと環境…

5年 ago