ECMAScript 5th Editionで改善された3rd Editionの項目

ざっと、5th Editionのドラフトを眺めてみて、3rd Editionの仕様の不備と思っていた部分が改善されているかどうかを調べてみた。以下、v3は3rd Edition、v5は5th Editionのこと。

  1. for in文のinの右のパラメータがnullの場合
  2. Annexにもちゃんと記述されているが、v3では for (var i in null) のようにinの右のパラメータに対してToObject()が実行されるため、それがnullの場合にはTypeError例外が発生する仕様になっていた。実際のブラウザのJavaScript実装ではそのような例外が発生することはなく、for本体が実行されない動作になっている。v5ではToObject()を実行する前に、それがnullかundefinedであるかをチェックする記述が追加されている。
  3. 文のない関数本体
  4. v3では文のない関数本体の扱いが微妙である。

    function foo() {}
    

    これはv3では文法的には自動セミコロン挿入機構によって

    function foo() {;}
    

    と等価と解釈することで成立する構文であるが、v5ではFunctionBodyであるSourceElementsがオプションになったため、文のない関数本体が構文的に直接受理されるものとなっている。実はこれはv2では元々そうなっていた。

  5. 文字列あるいは文字オブジェクトの配列アクセス
  6. Stringクラスに[[GetOwnProperty]](P)メソッドが定義されたので、文字列中の文字をcharAt()以外にも配列表記でアクセス方法が正式に導入された。実は、v3では

    var c = "hello"[2];
    var s = new String("abcdefg");
    var p = s[4];
    

    のような配列アクセスは規格では定義されていなかった。

  7. 複数行の文字列
  8. ほとんどのJavaScript処理系では文字列中に改行があっても問題なく受け付けてしまうが、規格的には文法違反。1つの文字列を複数行に記述するにはv5ではバックスラッシュでエスケープすればよい。

    var s = "abcdefg\
    hijklmn\
    opqrstu";
    

    既に多くの処理系で実装されていることではあるが。(はてな記法では認識されないみたい)

  9. NaN, Infinity, undefinedが定数に

  10. v3ではグローバルオブジェクトのプロパティであるInfinity, NaN, undefinedがreadonlyでなかったため、ユーザが自由に値を書き換えることができてしまった。やっぱりこれは問題だと感じていたがv5ではreadonly(v5の用語では[[Writable]]がfalse)になった。ちなみに、v3ではこれらの値は下記のコードで簡単に再定義することはできる。

    var NaN = 0/0;
    var Infinity = 1/0;
    var undefined = void 0;
    

一方、typeof nullの結果は依然として"object"であるが、個人的には"null"の方が整合性が取れていると思う。後方互換性維持のためか?

規格書のAnnex DとEにもいろいろ細かく書かれているが、とりあえず、今回はここまで。