javascript:alert([].sort.call(null)) == [object window] の謎

JavaScript 難しい。 ECMAScript5の "use strict" 時の [].sort.call(null) の挙動に関する議論
6
Atsushi Takayama @edvakf

javascript:alert([].sort.call(null)) これで window オブジェクト取れるのなんで?

2010-02-17 15:14:52
テラマコ @teramako

【急募】 RT @edvakf: javascript:alert([].sort.call(null)) これで window オブジェクト取れるのなんで?

2010-02-17 15:17:59
テラマコ @teramako

@edvakf むむむ、全然分からない。難しいですね。orz

2010-02-17 15:26:37
Atsushi Takayama @edvakf

Worker の中でやったら [object DedicatedWorkerGlobalScope] となった。当然だけど。

2010-02-17 15:27:48
kei-s @kei_s

. @edvakf @teramako ここの 15.3.4.4 じゃないでしょうか "thisArg が null または undefined の場合、呼出された関数は this 値としてグローバルオブジェクトを渡される" http://bit.ly/bMp9wI

2010-02-17 15:34:41
Piro🎉"シス管系女子"累計4万部突破!!🎉 @piro_or

@kei_s @edvakf @teramako あと、ECMAScript仕様書の15.4.4.11では「sortのthisがArrayでない時の挙動は実装依存」ともありますね。その両方が組み合わさってこうなってる?

2010-02-17 15:39:30
xulapp @xulapp

@edvakf call(null) は call(グローバル) と同じで、sort は this 値を返すことになっているのでそうなるんだと思います。

2010-02-17 15:41:30
Atsushi Takayama @edvakf

@kei_s @piro_or @xulapp なーるほど。理解できました。実装依存となってるのは残念です… "use strict" だと global = (function(){return this})(); がエラーになるので。

2010-02-17 15:45:04
Atsushi Takayama @edvakf

お、早速返事がもらえた。http://webreflection.blogspot.com/2010/02/jslint-bad-part.html#1641595776929548932 window が length プロパティを持ってるからとか。知らないw

2010-02-17 15:47:18
Atsushi Takayama @edvakf

あ、でも call(null) でグローバルオブジェクトが入るのは "use strict" では消えるらしい…

2010-02-17 15:48:03
つっくん(javascripter) @javascripter

@edvakf a.sort()がa自身を返すので、.sort.call(null)は.sort.call(window)と同じでwindowを返す。同様に[].concat.call(null)は[window]となる(a.concat()!=aなので配列以外は配列に包まれる)

2010-02-17 15:50:28
kei-s @kei_s

@piro_or 理解できた!これを機に ECMAScript の仕様をサクっと引けるようにしておきます

2010-02-17 15:50:54
Piro🎉"シス管系女子"累計4万部突破!!🎉 @piro_or

@edvakf 確かにテキトーなページで試してみるとlengthが0ですね。その後this(nullだったのがglobal objectになる)が返されて、結果としてwindowが返ってると。

2010-02-17 15:55:20
Atsushi Takayama @edvakf

@javascripter http://j.mp/aVhIq2 によると、window.length があるために Array じゃないのに sort がエラーにならないそうです。おもしろいですね。

2010-02-17 15:59:29
Atsushi Takayama @edvakf

ES5 の仕様読んでるけど "use strict" だと call(null) が使えないってどこに書いてあるのかわからない。

2010-02-17 16:05:37
つっくん(javascripter) @javascripter

@edvakf o={};[].sort.call(o)==oでソートされない、http://j.mp/aXPsyl でwindowの0と1のtoStringを書き換えてからsortすると順序が変わるのでwindowはsortされてますね(window[0]はwritable)

2010-02-17 16:14:26
つっくん(javascripter) @javascripter

@edvakf lengthの有無はエラーに関係なく、windowはarray-likeなのでlengthが0だと何も起きないが、sortの安定性は不定なのでframeのあるサイトで[].sort.call(null)するとwindow[0]とかが変更される可能性があります。

2010-02-17 16:21:37
Atsushi Takayama @edvakf

javascript:alert( function(){return this}.call(null) ) がいいかも。

2010-02-17 16:25:01
shogo ohta @os0x

@edvakf PDF119ページの冒頭のNOTEにあります。callでの挙動は、strict限定の話ではないみたい

2010-02-17 16:31:55
Atsushi Takayama @edvakf

use strict じゃなくても call(null) は使えないって、ちょっと問題出そうな気がする…

2010-02-17 16:35:38
Atsushi Takayama @edvakf

あれ、でもおかしい、別のところに、thisArg が null or undefined だったら global に置き換えろと書いてあったぞ。

2010-02-17 16:37:08
shogo ohta @os0x

@edvakf こっちはエラーではなく、globalがundefinedになる、だと思います、たぶん

2010-02-17 16:37:38
Atsushi Takayama @edvakf

@os0x 58ページの Else if thisArg is null or undefined, set the ThisBinding to the global object. とどう関わってくるのか気になるところです。

2010-02-17 16:38:14