ECMAScript 5の仕様がが今週、リリースされた(pdf)。ECMAScriptは一般的にはJavaScript™として知られている。最新バージョンでは、基本ライブラリに改善が加えられている一方、一般的でありがちなコーディングミスを特定し、除去するためにより厳格なランタイムモードが導入された。
ECMAScript 4を合理化しようという初期の試みは大失敗に終わった。結局、Adobe社のActionScriptだけが提案された変更点に対応しただけだった。ECMAはバージョン4の仕様もリリースできなかった。バージョン4の仕様では、様々なグループの実装に悪影響を与えてしまうからだ。また、そのような問題がある限り、ブラウザもサポートできない。
ここ数年にわたって、JavaScriptのエンジンに大規模な改善が加えられた。例えば、NitroやTraceMonkeyなどだ。その結果、JavaScriptはコラボレーションツールの分野で利用できるほど高性能になった。例えば、Google Waveはそのようなオンラインアプリケーションの事例のひとつだ。また、最近リリースされたGWT 2.0の一部としてSpeed TracerというGoogle Chromeの拡張がある。これは、JavaScriptのアプリケーションの性能を最適化するツールだ。
近年のこのような状況をふまえ、ECMAScript 5は現在使われているバージョン3との後方互換性の確保を目指し(各ブラウザが素早く対応できるようにするために)、同時に開発者が一般的なコーディングミスを犯さないようにするために、より厳しい制約を提供する。
Strict mode
strict modeを導入する目的は、ECMAScriptアプリケーションを開発するときに発生するコーディング上の一般的な問題を避けることだ。ひとつのユニット(スクリプトまたはファンクション)の中に、次のような文字列リテラルを書くことでこの制約を有効にできる。
"use strict;"
このリテラルは従来のランタイム上では何の影響もないが、バージョン5がターゲットとする新しいランタイム上ではstrict modeに切り替わる。スクリプトのトップに記述すればそのスクリプト全体が、ひとつのファンクションに記述すればそのファンクションが、strict modeになる。したがって、strict modeを適用したコードとそうでないコードを混在させることができ、既存のコードの改善にも利用できる。では、strict modeにすると実際にはどうなるのだろう。
- 変数は利用する前に宣言しなくてはならない。言い換えれば、
i=3
という書き方はランタイムエラーになる。var i=3
としなければならない。(i
がこのスコープ内にはないという前提) - Evalは予約語になる。また、eval内で新しい変数を導入できなくなる。したがって、
eval("var i=3"); print(i);
と書くと例外が発生する。 - 8進数のリテラルは使えない。したがって
010
は10であり、8ではない。 - configurableフラグがfalseに設定されている引数や関数、変数やその他の属性に対して、
delete
演算子が使えない。 - はエラーの原因になりやすい
with
ステートメントは使えない。構文エラーと見なされる。 - 同じ名前で引数が重複しているファンクションは定義できない。
- オブジェクトは同じ名前の属性を持てない。
arguments
とcaller
変数は不変になる。- グローバルオブジェクトへのアクセスはランタイムエラーになる。
ライブラリの拡張
基本ライブラリに対して、次のような拡張が加えられている。
- DateがISO8601形式の日付を生成できるようになる(例えば
20091209T12:34:56Z
)。パースもできる。 - Stringに
trim()
メソッドが組み込まれる。 - 新しい
JSON
オブジェクトは、JSON形式のデータを効率的に生成するためにparse
とstringify
をサポートする。eval
と似ているが、セキュリティを考慮した実装がないのでコードを少なくできる。加えて、RFC 4627に仕様化されているJSONObject
やJSONArray
だけでなく、どのようなJSONValue
も使える。(4627はJSON-Text
を定義しているが、これはオブジェクトか配列に制限されている。) - Prototypeのbind()と同じ構文で
bind
が組み込まれた - Arrayが標準的なファンクションをサポートするようになる。例えば
indexOf()
やmap()
、filter()
そしてreduce()
など。 - オブジェクトは
seal()
(新しい属性の追加と既存の属性の削除ができなくなる)とfreeze()
(すべての属性が読み取り専用になり、属性の追加と削除もできなくなる)が利用できる。 Object.keys()
を使うとそのオブジェクトのすべてのenumerableな属性を一覧できる。Object.getOwnPropertyNames()
を使うとすべてのenumerableと非enumerable属性を一覧できる。Object.getPrototypeof()
を使うとそのオブジェクトのprototypeを返す。
要約
JSONのパース機構の標準サポートとstrict modeは開発者に多大な恩恵を与える。これらの機能を使えばPrototypeや必要な拡張ライブラリのためにコードをより小さなライブラリへ変換できる可能性がある。JSONストリームからISO形式にパースされた日付は以前よりもはるかに移植が簡単になる。将来は日付を表す形式のデファクトスタンダードになるだろう。また、後方互換性が確保され、Prototypeのような既存のライブラリからヒントを得ているので、比較的近い将来のうちに開発者やブラウザは新しいJavaScriptの特徴になじむだろう。