ひびのログ

日々ではないけどログを出力していくブログ

ECMAScript2019 に入りそうな構文メモ

執筆時点で、Stage3 のものをピックアップします。 タイトルは「ES2019に入りそう」となっていますが、本当に入るかは保証しません。

策定中の機能はどんなんがあるのかなーというのをちらっと調べたメモ書きです。

リポジトリは以下です。

github.com

Function.prototype.toString revision

関数に対して.toString()を実行した場合の挙動が改善される。

  • JS(ECMAScript)で書かれた関数はソースコードをすべて表示する。
  • 組み込み関数やバインドされた関数エキゾチックオブジェクトは「NativeFunction」を返す。
  • JS(ECMAScript)で書かれていない関数の場合も「NativeFunction」を返す。
  • FunctionGeneratorFunctionコンストラクタで動的に作成された関数オブジェクトは、ソースコードを組み立てる必要がある。
  • その他のオブジェクトはTypeErrorをスローする。

雑感

ソースを表示するのは Chrome や Firefox がやっているがそれのこと?

バインドされた(以下略)っていうのが何者なのかがわからない。 bind()でthisが書き換えられた関数オブジェクトのこと?

最後の「その他のオブジェクトはTypeErrorをスローする。」っていうのは、関数に限ってってことでいいのか?

import()

動的インポート。 巻き上げは起こらない。 文字列リテラルだけでなく、変数も受け入れる。

モジュールの中に書いた場合は、そのモジュールが読み込まれるときに評価されるが、評価されなければいけない依存関係を確立しない(?)。

静的には解決できないけど、実際に実装されるときには、文字列リテラルのように単純なケース(import 先のソースが変わらない場合?)は、よしなにやってくれるかもしれない。

雑感

TypeScript 2.4 で実装されている(静的に解決される?)。 require()と似ているがそちらは同期的で、import()は非同期。 ブラウザでの初回ロードの負荷軽減になる。

import()されるモジュールの中にimport()がある場合などは使えない? 一応代替案の await import みたいなものが作られつつあるらしい。

実際入ったら、通常のimport xxx from "xxx"との使い分けに困りそう。

Optional catch binding

catch 節の変数定義が、いらないのなら省略できる。

try {
    // do something
} catch {
    // error!
}

雑感

別の機能へのフォールバックとかに使える。 parseInt()で使えそうだと思ったけど、エラーをスローするのは Java……

これが実装されようと、エラーの握りつぶしは悪と心得よ。

Private instance methods and accessors・Class Public Instance Fields & Private Instance Fields

Java とかみたいに、フィールド宣言を直接かけるようになる。 コンストラクタでの初期化によってフィールドを宣言することが不要になる。

また、プライベートメソッド・フィールドが定義できるようになる。

class TestClass {
    publicField = 0;
    #privateField = 0;

    constructor() {
    }

    get #field() { return #privateField; }
    countup() { this.#field++; }
}

class 宣言のときだけ有効で、動的に追加したフィールドやメソッドには適用されない。

雑感

GitHub の例を見ると、ゲッター中のプライベートフィールドへのアクセスはthisが書いてないが、他の場所やメソッド呼び出しにはthisがついている…… ただの脱字?

個人的に構文微妙だなーと。 Javaとかみたいに修飾子でやるほうが好き。 あとはconstを書かせてくれ! ……プライベートフィールドでやれって話か。

Stage2 の「Static class fields and private static methods」は修飾子でやってるんだからこっちも揃えたほうがいい気がする。

ないよりは断然あったほうがいいので嬉しい。

Array.prototype.{flatMap,flatten}

公式サイトがとっても分かりづらいので、一般的な話。

flattenは、配列がネストされているときに、指定した階層まで平らにする。

[[1, 2], 3, 4, [[5, 6], 7] 8, 9].flatten(2)
// => [1, 2, 3, 4, 5, 6, 7, 8, 9]

flatMapは、mapしてflattenする。

[[1, 2], 3, 4, [5, 6, 7] 8, 9].flatMap((elm) => elm + [0])
// => 1, 2, 0, 3, 0, 4, 0, 5, 6, 7, 0, 8, 0, 9, 0

flatMapは多段ネストされていた場合どうなるかわからない!

どうやらFlattenIntoArrayなるものもあるらしい。 見た感じ、flattenした結果を別の配列に入れるものっぽい?

雑感

これが入ると配列がモナドとして扱える? モナドよくわからないけど。

Numeric separators

10_000_000 === 10000000

雑感

これ欲しかった。 別の進数でも使える。

String.prototype.{trimStart,trimEnd}

trim()の頭だけ版と後ろだけ版。

雑感

使い所ある? 強いて言えばtrim-marginみたいにインデントを削除するときに、正規表現の代わりに使うことで速度が上がる?

github.com

最後に

全部入るとは思わないけれど、どれかしらは入るんじゃないかなーと感じます。

import()は結構取り上げられているけど、まだテストがマージされていない状態なので、どうなるかわかりませんね。