レポート

Domenic Denicola氏,JavaScriptの今を紹介 ~東京Node学園祭2015 基調講演

この記事を読むのに必要な時間:およそ 4.5 分

JavaScriptの未来

これからのJavaScriptを語る上で一番重要なことはECMAScriptの仕様がGitHubにホスティングされるようになったことです。これまではWordによって管理されていましたが,GitHubで管理することでリビングスタンダードとして参照され,誰でも貢献できるようになったのです。

次に大事なことは,仕様のバージョンがなくなったことです。言語の仕様で大事なことはランタイムやブラウザでその機能が実装されているかどうかということです。今後はバージョン番号を廃し,GitHub上に公開されているドキュメントがリビングスタンダードとして参照されるのです。このリビングスタンダードと違う場合,実装しているベンダにフィードバックすると良いでしょう。

そして,ES2015に含まれていないが既に誰かが取り組んでいる,もしくは準備ができているものを紹介しました。

まずはasync/awaitです。この構文はジェネレータにも似た構文ですが,ジェネレータよりも簡潔に書くことができます(リスト4)⁠また,Microsoft EdgeやMozilla Firefoxでは既に使える構文です。

リスト4 async/await

async function getUserImages() {
  const response = await fetch("http://example.com/users");
  const users = await response.json();

  return Promise.all(users.map(async (u) => {
    return {
      name: u.name,
      image: (await fetch(u.imageUrl)).body
    };
  }));
}

次に紹介するのはSIMD.jsです。これはハードウェアで動作するときのためのもので,よりCPUに近いAPIを使うことができるため,さらなる高速化が可能となります(リスト5)⁠

リスト5 SIMD.js

for (let i = 0; i < max_iterations; ++i) {
  const z_re24 = SIMD.float32x4.mul(z_re4, z_re4);
  const z_im24 = SIMD.float32x4.mul(z_im4, z_im4);

  const mi4    =
SIMD.float32x4.lessThanOrEqual(SIMD.float32x4.add(z_re24, z_im24),
four4);

  if (mi4.signMask === 0x00) {
    break;
  }

  const new_re4 = SIMD.float32x4.sub(z_re24, z_im24);
  const new_im4 = SIMD.float32x4.mul(SIMD.float32x4.mul(two4, z_re4), z_im4);
  z_re4         = SIMD.float32x4.add(c_re4, new_re4);
  z_im4         = SIMD.float32x4.add(c_im4, new_im4);
  count4        = SIMD.int32x4.add(count4, SIMD.int32x4.and(mi4, one4));
}

ここまでは既に誰かが取り組んでいるものを示しましたが,これ以降はコンセプト段階だけれども面白い構文を紹介しました。

1つめはバリュータイプです。これはメモリを効率よく活用するための構造体を定義する構文や,CSSで使われる単位をリテラルとして付加する構文などが含まれています(リスト6)。

リスト6 バリュータイプ

// 64ビット整数
const fifteen = 5UL + 10UL;

// メモリ効率の良い構造体
const Point = new ValueType({ x: float64, y: float64 });
const point = new Point({ x: 1.5, y: 2.4 });
assert(point === new Point({ x: 1.5, y: 2.4 }));

// カスタムリテラルとオペレータオーバーロード
const romaineLettuce = 0x3B5323FFrgba;
const length = 50percent + 10em + 5px;
el.css.width += 2rem;

2つめはデコレータです。これはメソッドを任意のメソッドに変更する構文で,元々AngularJSで使われている構文です(リスト7)⁠リスト7ではパフォーマンスの必要なメソッドに対してデコレータで実行時間を測定するように変更しています。

リスト7 デコレータ

class BusinessLogic {
  @performance
  doImportantComputation() {

  }
}

(new BusinessLogic()).doImportantComputation();
// => doImportantComputation: 102ms

3つめはキャンセル可能Promiseです。これは通常のPromiseがどのような状態でもその動作をキャンセルできる機能です(リスト8)⁠リスト8は,複雑な処理をするPromiseをキャンセルボタンを押すことでキャンセルするような例です。

リスト8 キャンセル可能Promise

startSpinner();

const p = fetch(url)
  .then(r => r.json())
  .then(data => fetch(data.otherUrl))
  .then(res => res.text())
  .then(text => updateUI(text))
  .catch(err => showUIError(err))
  .finally(stopSpinner)

cancelButton.onclick = () => p.cancel();

4つめは非同期イテレータです。これはasync/await構文とfor-ofを組み合わせたもので,Node.jsのStreamの処理などがこれによって書き換えられるコードの代表例です(リスト9)⁠

リスト9 非同期イテレータ

async function* directoryEntries(path) {
  const dir = await opendir(path);

  try {
    let entry;
    async for (const entry of readdir(dir)) {
      yield path.resolve(entry);
    }
  } finally {
    await closedir(dir);
  }
}

5つめはモジュールローディングです(リスト10)⁠最近ホットな話題はモジュールロードですが,仕様レベルでいうとまだ何も決まっていないというのが実情です。リスト10に示すコードが最小の機能だと考えていて,これで合意がとれれば仕様策定を進めていけると考えています。

リスト10 モジュールローディング

<script type="module">
import a from "./a.js";
import { b } from "../b.js";
import $ from "https://cdn.example.com/jquery.js";
</script>

そして最後はWebAssemblyです。これはまだ謎に包まれていて,まだ全貌が分かっていません。現状は,Google, MicrosoftやAppleもエンジニアを投入していて新たなバーチャルマシンを作っているようです。C++やJavaなどからコンパイルして使うことを想定して作っているようです。GitHub上でドキュメントを読むことができます。

まとめ

JavaScriptはその20年の歴史の中でも今が1番大きな転換点を迎えているといっても過言ではないでしょう。そのような中でDomenic Denicola氏は,これまでの歴史とこれからについて構文の紹介や新機能の紹介を,スニペットを交えて講演しました。

著者プロフィール

小林貴也(こばやしたかや)

福井工業高等専門学校を卒業後いろいろあって株式会社サイバーエージェントへ入社。JavaScriptを書いたりRailsを書いたりしている。映画をみたりDJをしたりゲームをするのが趣味。

Webサイト:http://jgs.me
Twitter:@neo6120

コメント

コメントの記入