Introduction

ブログ内検索

  • このサイトの記事を検索 by Google

おすすめの一冊!

無料ブログはココログ

« iframe 要素の onload ハンドラ | トップページ | RESTful のお勉強 »

2011-05-14

微妙な配列リテラル


ちょっと気になる JavaScript ネタを発見。

    Javascriptが難しくてわからないので誰か教えてください
      --  Aduca

これは JavaScript の配列リテラルの仕様から説明ができます。

JavaScript の仕様書(というかベースとなっている ECMAScript の仕様書)を
ちょっと見てみましょう:

    ECMA-262
    ECMAScript Language Specification
    5th Edition / December 2009
    http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf


p.63 の "11.1.4  Array Initialiser" の第2段落にそれらしきことが書いてあります。

ざっくり訳してみます。
配列要素は、要素リストの先頭でも、中間でも、末尾においても、省略されうる。 有意な式がコンマの前に置かれていない場合、つまり「いきなりコンマで始まる」 とか「別のコンマのすぐ後に続けてコンマが置かれた」というケースでは、 省略された要素は配列の長さに含まれ(配列の長さが増加し)、それに続く要素に 割り当てられる添字がそのぶんだけ大きくなる。省略された要素は定義されない (undefined となる)。もし、要素リストの最後の要素が省略された場合、 その要素は配列の長さに含まれない。
つまり、次のようになると考えられます。
> [] ⇒ 最終要素しか無くて、その要素が省略されているので、長さ 0 の空配列。 > [,] ⇒ カンマの前にある先頭要素が省略されているので、その値は undefined で、 最終要素は省略されているので無視。結果として長さ 1 の配列。 > [,,] ⇒ カンマの前にある先頭要素が省略されており、次のカンマも連続しているので、 先頭の2個の値はいずれも undefined である。 最終要素は省略されているので無視。結果として長さ 2 の配列。
処理系の表示によってはまぎらわしいのですが・・・
> [] [] > [,] [] > [,,] []
空の要素に見えても要素数はちゃんと保持されています。
> [].length 0 > [,].length 1 > [,,].length 2
次に、toString() の結果についてですが、 上記仕様書の "15.4.4.2 Array.prototype.toString()" (p.123) を 見てみると、内部的には join を呼んでいるようです。 つまり、[].toString()[].join() と同じ。 仕様書の "15.4.4.5 Array.prototype.join(separator)" (p.125) を 見てみると、次のようなルールがわかります。   ・空の配列には空の文字列が返る   ・1要素の配列ではその要素そのものが返る   ・複数の要素があればカンマで連結したものが返る   ・undefined な要素は空文字列になる。   ・区切り文字 (separator) が省略された場合はコンマが使われる。 というわけで、次のような挙動となります。
> [].toString() ←空の配列なので空文字列 "" > [,].toString() ←長さ1の配列なのでカンマで区切られない "" > [,,].toString() ←長さ2の配列なのでカンマで区切られる ","
これで仕様通りなのです。 結局のところ、undefined な要素しか含まない配列の 簡易表示がイマイチ、という話なのかもしれませんね。
> [,,,,] [] > [,,,1,] [undefined, undefined, undefined, 1] > [,,,1,,,] [undefined, undefined, undefined, 1] > [,,,1,,2,] [undefined, undefined, undefined, 1, undefined, 2]
どうも、配列の末尾の undefined な要素は省略されるお約束っぽい。 まぁ、new Array(50) とか書いたときに "undefined" と 50個も表示されるのも困るので、まぁ、妥当といえば妥当かもですが・・・ p.s. 処理系の実行例は Google Chrome のコンソールのものです。 Firefox (Firebug) では undefined な要素がきちんと全部表示されました。

« iframe 要素の onload ハンドラ | トップページ | RESTful のお勉強 »