ECMA 5への参照は明確にする必要があります。
ECMA-262エディション5を意味すると思います。ECMA-262(別名ECMAScript、またはより正確にはJavascript)は、インターネットブラウザに実装されている一般的なスクリプト言語です。Edition 5.1標準から:
次の手順は、コントロールが関数オブジェクトFに含まれる関数コードの実行コンテキストに入り、呼び出し元がthisArgを提供し、呼び出し元がargumentsListを提供するときに実行されます。
- 関数コードが厳密なコードである場合は、ThisBindingをthisArgに設定します。
- そうでない場合、thisArgがnullまたは未定義の場合は、ThisBindingをグローバルオブジェクトに設定します。
- そうでない場合、Type(thisArg)がObjectでない場合は、ThisBindingをToObject(thisArg)に設定します。
- または、ThisBindingをthisArgに設定します
- ...(「これ」についてではない)
「グローバルオブジェクト」という用語は、スコープチェーンの最上位にあるオブジェクトを指します。ブラウザの場合、これは「ウィンドウ」オブジェクトですが、これは実装の選択です(Windowsスクリプトホストには非表示のグローバルオブジェクトがありますが、厳密なモードがないため、非修飾参照がそのプロパティにアクセスし、グローバル「自己」はありません)。また、「ストリクトモード」は明示的に有効にする必要があります。そうしないとアクティブになりません(標準のセクション14.1)。そのため、未定義の「this」は、厳密モードがアクティブではない「ECMA 5」のグローバルオブジェクト(ウィンドウ)に解決されます。
したがって、質問に対する答えは次のとおりです。
「this」は常に関数を呼び出すオブジェクトを指します。関数がオブジェクトによって呼び出されなかった場合(つまり、メソッド呼び出しではない場合)、「this」(関数に渡される)は「未定義」です。ただし、strictモードを使用しない場合、未定義の「this」がグローバルオブジェクトに設定されます(上記のルール2)。
「自己」には特別な構文上の意味はなく、単なる識別子です。ブラウザはwindow.self(グローバルウィンドウオブジェクトのプロパティのみ)= windowを定義する傾向があります。これにより、「self」への修飾されていない参照は「ウィンドウ」と同じになります。ただし、「self」は、上記の「var self = this;」などの囲みスコープ内で再定義されています。「this」を再定義してください。
上記の例の完全な説明は次のとおりです。
outer func: this.foo = bar
// "this" refers to the invoking object "myObject"
outer func: self.foo = bar
// "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
inner func: this.foo = undefined
// "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
inner func: self.foo = bar
// self resolves to the variable in the enclosing scope which is still "myObject"
例の興味深いバリエーションは、内部関数への参照を返すことによってクロージャーを作成します。
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
return function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
};
}
};
var yourObject = {
foo: "blat",
func: myObject.func() // function call not function object
};
console.log("----");
yourObject.func();
生産
outer func: this.foo = bar
outer func: self.foo = bar
----
inner func: this.foo = blat
inner func: self.foo = bar
yourObjectによって呼び出されるまで、内部関数が呼び出されないことに注意してください。つまり、this.fooはyourObject.fooになりましたが、自己は依然として、内部関数オブジェクトが返されたときにmyObjectだった(そして結果のクロージャではまだだった)囲んでいるスコープの変数に解決されます。したがって、内部関数内では、「this」は内部関数を呼び出すオブジェクトを指し、「self」は内部関数への参照を作成するために外部関数を呼び出したオブジェクトを指します。
要約の要約を要約すると、「this」は言語標準によって定義され、「self」は定義者(ランタイムインプリメンターまたはエンドプログラマー)によって定義されます。