🤷‍♂️

ECMAScriptのproposalsを見て暇をつぶす話

2022/12/07に公開1

はじめに

Amebaの広告プロダクトチームでフロントエンドエンジニアをやっている@zenn1234です。

この度、弊社の広告横軸組織PTAが運営するアドベントカレンダーに急遽参加することになりました。

拙い文章になりそうですが、頑張って書いていこうと思います。

何について書くか?

問題は、何にも書くことがない、ということです。

ネタが浮かばない。

このままだと運営さんからの おこられ が発生してしまうので、無い脳みそを使ってどうにかしてネタを絞り出します。

フロントエンジニアがブログネタに窮した時の救世主

そこで登場するのが ECMAScriptのproposalsを読み込む という作法です。

過去に数多のフロントエンジニアがアドベントカレンダーのネタに詰まり、その度にECMAScriptのproposalsに救ってもらってきた歴史があります。

なので今回もECMAScriptのproposalsを眺めつつ、気になったものについて雑な感想をつけるスタイルで行こうと思います。

ECMAScriptのproposalsとは?

ECMAScriptについてはこちらを見ていただくとして、proposalsというのは文字通り提案されている仕様です。

ここで管理されていて、以下のようにStageという段階が定められています。

Stage Code 説明
Stage 4 Finished 最低2つ以上のプロジェクトで実装されている
Stage 3 Candidate 仕様が完成しフィードバックを受けている
Stage 2 Draft APIや構文が定義されている
Stage 1 Proposal 目的や解決方法を示す
Stage 0 Strawman アイデア段階

Stage 3

現在実装待ちの仕様を見ていきます。

以下、気になったものだけ記載しているので、Stage 3の一覧を全て見たい方はこちらをご覧ください。

Import Assertions

JSONファイルをimportで読み込めたり、WebAssemblyを読み込めたり。

  import json from "./foo.json" assert { type: "json" };
  import("foo.json", { assert: { type: "json" } });

  new Worker("foo.wasm", { type: "module", assert: { type: "webassembly" }; });

Temporal

ついに日付フォーマットがネイティブでできるように!
と思ったらフォーマットは自力でやらないといけないらしく、だったらこれ何の意味があるんかと。。
結局 Moment.js やら Day.js が必要なままになりそう。

  const instant = Temporal.Instant.from('1969-07-20T20:17Z');
  instant.toString(); // => '1969-07-20T20:17:00Z'
  instant.epochMilliseconds; // => -14182980000

Array Grouping

配列をグループ化したObjectを返す。
結構マニアックですが、便利だなと思うタイミングがいつか来そう。

const inventory = [
  { name: 'asparagus', type: 'vegetables', quantity: 5 },
  { name: 'bananas',  type: 'fruit', quantity: 0 },
  { name: 'goat', type: 'meat', quantity: 23 },
  { name: 'cherries', type: 'fruit', quantity: 5 },
  { name: 'fish', type: 'meat', quantity: 22 }
];
const result = inventory.group(({ type }) => type);

/* result:
{
  vegetables: [
    { name: 'asparagus', type: 'vegetables', quantity: 5 },
  ],
  fruit: [
    { name: "bananas", type: "fruit", quantity: 0 },
    { name: "cherries", type: "fruit", quantity: 5 }
  ],
  meat: [
    { name: "goat", type: "meat", quantity: 23 },
    { name: "fish", type: "meat", quantity: 22 }
  ]
}
*/

Change Array by Copy

配列の操作に以下が追加される。

  Array.prototype.toReversed() -> Array
  Array.prototype.toSorted(compareFn) -> Array
  Array.prototype.toSpliced(start, deleteCount, ...items) -> Array
  Array.prototype.with(index, value) -> Array

New Set methods

Setの操作に以下が追加される。

  Set.prototype.intersection(other)
  Set.prototype.union(other)
  Set.prototype.difference(other)
  Set.prototype.symmetricDifference(other)
  Set.prototype.isSubsetOf(other)
  Set.prototype.isSupersetOf(other)
  Set.prototype.isDisjointFrom(other)

Stage 2

ドラフトの仕様を見ていきます。
現時点での仕様なので、仕様変更されたり、このままお蔵入りになったりする可能性があるので注意してください。

以下、気になったものだけ記載しているので、Stage 2の一覧を全て見たい方はこちらをご覧ください。

Record & Tuple

従来のObject, Arrayとは違い、immutableなデータ構造を扱うことができる。
Immutable.js とか Immer とか使ってたのが不要に。

  #{}
  #{ a: 1, b: 2 }
  #{ a: 1, b: #[2, 3, #{ c: 4 }] }
  #[]
  #[1, 2]
  #[1, 2, #{ a: 3 }]

Pipeline Operator

パイプが使えるようになるので処理の流れが直感的に。
JSの書き方が大幅に変わりそうですね。es2015以来のインパクトがありそう。
仕様はまだブレそう。

  value |> one(%) |> two(%) |> three(%);

疲れた

Stage 1 と Stage 0 についても面白そうなのを取り上げようと思ったのですが、意外と物量があり時間がなくなってきたので今回はこの辺でおしまいです。

ありがとうございました。

Discussion

クロパンダクロパンダ

Temporal はタイムゾーンを"扱わない"みたいな選択ができる、時間を自分が扱いたい形式で扱える点が素晴らしいと思ってるのでフォーマットできないなら意味ないじゃんはいささか軽率かと。(まあ API が結構ローレベルだからハイレベルなラッパーが出てくるのかなとは思ってますが)

ドキュメントが日本語訳されてるので是非
https://tc39.es/proposal-temporal/docs/ja/index.html