2014-04-21

JavaScriptの配列初期化子

ECMAScript Edition 5.1を§11まで読み進めた。§11は、式だ。ようやく面白くなってきた。

§10は、この後の文面で使いまわすための、擬似的な処理を定義している。

さて、いよいよ具体的にコードとして書く、式のセクションを読んでいる。なかなか楽しいが、配列初期化子の文法が興味深かった。

配列初期化子、あるいは配列リテラルは、[ ]の中に要素を書く。

// 結果は要素数4の配列、[ 1, 2, 3, 4 ]
[ 1, 2, 3, 4 ] ;

配列初期化子には、Elisionという文法があり、途中の要素を省略できる。省略した要素は、undefinedである。

// 結果要素数4の配列、[ 1, undefined, 3, 4 ]
[ 1, , 3, 4 ] ;

なるほど、これはよく分かる。しかしよくわからないのは、「Elisionが配列の最後に使われた時には、配列の長さに寄与しない」という文面だ。つまり、最後のElisionは、無視されるのだ。

// 結果は3
[ 1, 2, 3 ].length ; 
// 結果は3
[ 1, 2, 3, ].length ;

たいていの言語ならば、文法違反とするところだが、実に不思議で例外的な文法だ。

しかし、それだけではない。要素が任意個のElisionだけの場合の文法も特別に定義されていて、その場合は、末尾のElisionも配列の長さに寄与するのだ。

[].length ; // 0
[,].length ; // 1, [undefined]
[1,].length ; // 1, [1, undefined]
[,,].length ; // 2, [undefined, undefined]
[1,,].length ; // 2, [1, undefined]

気持ち悪い。極めて気持ち悪い。例外に例外を重ねた文法で気持ち悪い。

さて、次はオブジェクト初期化子だが、どうもこれも、文法が気持ち悪そうだ。

文法の汚さ、パースしにくさでいえば、C++は悲惨なのだが、しかし、このような不思議な文法は多くない。JavaScriptの文法は気持ち悪い。

それでも、JavaScriptの文法や思想は、いまさら言うことではないが、面白い。

ドワンゴ広告?

この記事は超チューニング祭に向けてドワンゴ勤務中にECMAScript Edition 5.1を読みながら書いた。

そもそも、この超チューニング祭というのは、ユーザーによる企画だそうである。実は筆者も詳しいことを知らない。公式サイトが更新されて、基本ルールが追加されたが、この更新情報も事前事後に知らさるような特別なはからいは一切ない。そのため当日は、ドワンゴ社員であることによる不公平な情報差は発生しないだろうから安心してよろしい。

ところで、その更新されたルールによれば、当日編集できるソースコードは、HTML, CSS, JavaScriptだという。

「超チューニング祭 ~ニコニコを超快適にしてみた~ in ニコニコ超会議3」の問題点 - Webサイトパフォーマンスについてで指摘されているように、ボトルネックの大半はフロントエンドにないというのは、実際その通りだろう。複数のCSSやJavaScriptを結合したり、最小化したりといった小手先の技術は、小さな最適化に過ぎない。

では、勝利を狙うカギは、パフォーマンス以外の評価点、すなわちUIデザインだろうか。スマートフォン向けのデザインは、小さな画面サイズのため、とても単純にならざるを得ず、差別化を行いにくい。

ところで、現在、自由なスマートフォンがないので、筆者は携帯電話を所有していない。当日は極めて厳しい戦いを強いられることになりそうだ。

そして、そろそろ「広告」の定義について根本的な疑問が生じている。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

4 comments:

Anonymous said...

別に、不思議でも何でもないでしょう。最後が,で終わる場合についてはCやC++でも存在する文法なわけですし。
単に、それがElisionのせいで「,で終わった場合は『最終要素の後の,』なのか『Elisionによる空要素の追加』なのか区別がつかないので、仕様として前者であるものと規定する」というだけでは?

Anonymous said...

>[1,].length ; // 1, [1, undefined]
このコメントは // 1, [1] の誤りですね

ひよこ3分07秒 said...

undefinedが入るというのは正しくないです。何も入っていない、が正しい。

[undefined,1].map(function(x) { return x * 2 });

は[NaN,2]になりますが、

[,1].map(function(x) { return x * 2 });

は[,2]になります。

('0' in [undefined,1]) // => true
('0' in [,1]) // => false

Anonymous said...

配列リテラルという概念が好きです。
C++にはイニシャライザーリストさんが入りましたけど、なんか配列リテラルっていう感じじゃないんですよね。
完全に配列であるリテラルってなんかいいです。