虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

JavaScriptの最新規格調査(ECMAScript Proposals Stage3その1)

f:id:toranoana-lab:20191025110626j:plain

皆さんこんにちは。

Bloodborneが安売りしてたので今さら買って、日々ヤーナムの街に繰り出しているラボのY.Fです。

さて、今回は私が普段ウォッチしているJavaScript(ECMAScript)の規格について紹介したいと思います。

そもそもECMAScriptとは

今さら知ってるぜって方もいると思いますが、おさらいを兼ねて定義を引っ張っておきます。 いつものようにMDNさんに頼りましょう。

developer.mozilla.org

ポイントは、

  • JavaScript の中核となる言語は ECMAScript
  • 文法等々言語に必要な仕様の定義
  • Ecma TC39 によって標準化

というところでしょうか。平たく言うとECMAScriptとはJavaScriptの標準規格です。

規格を調べてみる

Ecma TC39 によって標準化 といってもどこで話し合いとかされて決められているの?と思うかもしれません。TC39に関しては、以下のリポジトリが存在します。

github.com

また、TC39にはStage 0からStage 4といった具合に、段階を経て標準化されていきます。各Stageについては、

  • Stage 0
    • Stage 1に満たないもの。または提出予定のもの
  • Stage 1
    • プロポーザルに関して何かしらの説明があるもの
  • Stage 2
    • 構文とセマンティクスについて説明されているもの
  • Stage 3
    • 実装とユーザーからのフィードバックが必要なもの
    • セマンティクス、シンタックス、APIについては説明が完了している
  • Stage 4
    • 取り入れ準備完了

といった感じです。更に詳細な各ステージの説明は以下

tc39.es

Stage 3を調査

ということで、Stage 4についてはすでに取り入れられる予定のものなので、JavaScriptの未来を探るにはStage 3を見てみるのが良さそうです。いくつかStage3を見てみて紹介してみたいと思います。

Class Public Instance Fields & Private Instance Fields

ES2015ではclassとメソッドは定義できるもののメンバフィールドの明示的な定義が無かったので、それの追加になります。

github.com

class Hoge {
  x = 100;
  // #がつくとprivate(詳細は下記)
  #y = 200;
}

単純にclass内に定義すると、メンバ変数として取り扱えるのは直感的だと思います。

Private instance methods and accessors

タイトル通りです。プロポーザルはこちら

github.com

ECMAScript 2015(以下ES2015)で導入されたclassに対して、privateメソッドなどを定義できるようにするプロポーザルです。シンタックスは以下のような感じです。

class Hoge {
  #fuga = "world";

  #helloWorld() {
    console.log(`Hello, ${this.fuga}`);
  }

  hogehoge() {
    helloWorld();
  }
}

To make methods, getter/setters or fields private, just give them a name starting with #. とあるように、メソッドなどの前に # がつけられているものがprivateとなるようです。

Static class fields and private static methods

これもタイトル通りstaticフィールドを追加するプロポーザルになります。

github.com

class Hoge {
  static hogehoge = 100;
}

// classオブジェクトに直接プロパティつけてしまう場合(これまでの書き方)
Hoge.fuga = 10000;

そのままstaticがつけられるようになっただけです。元々のJavaScriptではclassオブジェクトに直接つければ似たような事ができましたが、classが入ったのでこれで他の言語っぽく定義できるようになりそうです。 ちなみに上記で導入された#付きprivateメソッドもstaticにできます。

Nullish coalescing Operator

nullやundefinedの扱いを改善するためのプロポーザルです。

github.com

今までnullだったら何かを入れるみたいな処理は || を使って以下のように書くことができました。

const hogeNull = null;
const hogeUndef = undefined;
const hoge = 100;
const hogeEmpty = "";

let fuga = hogeNull || 1; //=> 1
fuga = hogeUndef || 2; //=> 2
fuga = hoge || 3; //=> 100
fuga = hogeEmpty || 4; //=> 4

ただし、この最後の例を見てもらうとわかるように、JavaScriptでfalsyとして扱われる値はすべて || の右辺がとられてしまっていました。 今回のプロポーザルは、厳密にnull系の値だったときのみ何かしら別の値を設定するシンタックスになります。

const hogeNull = null;
const hogeUndef = undefined;
const hoge = 100;
const hogeEmpty = "";

let fuga = hogeNull ?? 1; //=> 1
fuga = hogeUndef ?? 2; //=> 2
fuga = hoge ?? 3; //=> 100
fuga = hogeEmpty ?? 4; //=> ""

Optional Chaining

上記のものと似ているプロポーザルになります。

github.com

JavaScriptを書いていてよくあるケースとして、取得したエレメントが空だった場合を考慮して逐一チェック処理を書くといったものがあると思います。

const elem = document.getElementById("hogeInput");
const value = elem ? elem.value : undefined;

必要な処理ではあるんですが、場合によってちゃんとしたif文を至るところに書かないと見にくかったり、より複雑な処理を色んな場所に書かないと行けなかったりと結構面倒ではありました。

今回提案されている Optional Chaining を使うと以下のような感じで書くことができます。

const elem = document.getElementById("hogeInput");
const value = elem?.value; //=> elemなければエラーにならずundefined

先述した Nullish coalescing Operator をあわせて使うと初期値を自動で割り当てられてハッピーになれそうです。

const elem = document.getElementById("hogeInput");
const value = elem?.value ?? 0;

ちなみに単純な値の評価のみではなく、プロパティやインデックスアクセス用に ?.[] が用意されていたり、関数呼び出し用に ?.() が用意されてたりなどします。

まとめ

今回はStage3の中でもclass構文に関するものと、null安全にまつわるようなものについて書きました。TypeScriptではすでに取り入れられているものもあるあたり、TypeScriptが規格に与えている影響は大きそうだなと改めて思いました。

他にもプロポーザルを見てみるとまだまだ面白そうなものがたくさんあるので、日を空けて続きを書いて行きたいと思います。

P.S.

虎の穴では一緒に働く仲間を絶賛募集中です! この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。 yumenosora.co.jp

10/30(水)に『オタクが最新技術を追うライトニングトークイベント in 渋谷』を開催いたします。
一般参加者、LT参加者、どちらも募集しておりますので、ご興味のある方は是非ご応募ください! (ちなみに筆者もRust + WebAssemblyについて話します) yumenosora.connpass.com

前回のライトニングトークイベントのレポートはこちらから!

toranoana-lab.hatenablog.com

そのほか、過去に開催したライトニングトークの様子についてはこちらをご確認ください!

さらに、11/13(水)には第二回となるアーツ千代田での説明会を行います。こちらも是非ご応募ください!

yumenosora.connpass.com