厳密モードでjavascriptを使用するときに、匿名関数のthisが未定義なのはなぜですか?なぜこれが理にかなっているのか理解していますが、具体的な答えが見つかりませんでした。
例:
(function () {
"use strict";
this.foo = "bar"; // *this* is undefined, why?
}());
フィドルでテスト: http://jsfiddle.net/Pyr5g/1/ ロガーをチェックアウトします(firebug)。
これは、ECMAscript 262 edition 5まで、constructor pattern
、new
キーワードの使用を忘れました。 ES3でコンストラクター関数を呼び出すときにnew
を使用するのを忘れた場合、this
はグローバルオブジェクト(ブラウザーではwindow
)を参照し、グローバルオブジェクトを変数で上書きします。
それはひどい行動だったので、ECMAの人々はthis
をundefined
に設定することにしました。
例:
function myConstructor() {
this.a = 'foo';
this.b = 'bar';
}
myInstance = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance = myConstructor(); // oh my gosh, we just created a, and b on the window object
最終行は、ES5 strictでエラーをスローします
"TypeError: this is undefined"
(これははるかに良い動作です)
呼び出された関数のコンテキストに入る前にthis
オブジェクトをラップまたは変更する「ボクシング」と呼ばれるメカニズムがあります。この場合、関数をオブジェクトのメソッドとして呼び出していないため、this
の値はundefined
である必要があります。この場合、非厳密モードの場合、これはwindow
オブジェクトに置き換えられます。 strict
モードでは常に変更されないため、ここでundefined
になります。
で詳細を見つけることができます
https://developer.mozilla.org/en/JavaScript/Strict_mode
このスタックオーバーフローの答え によれば、this
を匿名関数内で使用できます。そのためには、最後に.call(this)
を呼び出すだけです。
(function () {
"use strict";
this.foo = "bar";
}).call(this);