ECMAScript 5 strict mode では call(null) がダメな理由

ECMAScript 5 strict mode では Function.prototype.call, Function.prototype.apply の第1引数に null ないし undefined を与えても、実行関数スコープの this 値がグローバルオブジェクトにならない理由。 あと、通常モードでは ECMAScript 3 互換がとれている(this 値がグローバルオブジェクトになる)理由。
2
Atsushi Takayama @edvakf

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

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

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

2010-02-17 16:25:01
Taku Watabe @taku_eof

@edvakf strict mode 時の Function.prototype.call 挙動については、仕様の P233 下から4つめのリスト項目に、どのセクションで説明されているかの参照が掲載されてます。あとはそれを追いかければ……。

2010-02-17 16:27:00
Atsushi Takayama @edvakf

@taku_eof 一番下にあったのですね。本編を読んでも出てこないわけだ。今から読みます。

2010-02-17 16:30:00
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
Atsushi Takayama @edvakf

あ、58ページに書いてあった。If the function code is strict code, set the ThisBinding to thisArg.

2010-02-17 16:42:00
shogo ohta @os0x

@edvakf そっちはcallでthisを明示してない場合です。良くある無名関数の実行などではthisはglobal objectになります。で、ここがstrictモードではnullです。

2010-02-17 16:42:41
Atsushi Takayama @edvakf

call したときはまだ thisArg が null のまま (これは ES3 から変更) だけど、entering function code で strict mode じゃなければ null を global にしろと書いてある。

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

strict mode なら thisArg をそのまま (global にしたり ToObject したりせずに) ThisBinding すると。

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

javascript:alert(function(){return this}.call()) は normal mode では window で strict mode だと undefined

2010-02-17 16:46:34
shogo ohta @os0x

あれ、nullじゃなくてundefinedかも…。

2010-02-17 16:46:55
shogo ohta @os0x

@edvakf Function.prototype.callを使っている場合、normal modeでもundefinedになるのでは?

2010-02-17 16:48:51
shogo ohta @os0x

いや、明示してなければならないか。function(){return this}.call()とfunction(){return this}.call(undefined)で違いがでるのかな。うーん。

2010-02-17 16:51:00
Atsushi Takayama @edvakf

@os0x 58ページの下のリストを見ていくと、strict なら thisArg をそのまま ThisBinding にして、そうじゃなければ、と続きます。なので normal mode では互換性が保たれます。

2010-02-17 16:53:49
shogo ohta @os0x

@edvakf なるほど、15.3.4.4 Function.prototype.callが呼ぶ13.2.1 [[Call]]のなかで、thisは10.4.3見ろとあるので、そうなりそうです。

2010-02-17 17:10:08