「なぜ JavaScript は混乱するのか」
そうではありません。オブジェクト プロパティへのアクセス方法を管理する特定のルール セットがあります。これらのルールが他のすべての OO 言語と同じではないというだけです。
「他の多くの OO 言語this
では、コードを読者に明示的にするためだけに使用されます」
Java などの一部の OO 言語でthis
は、コードを読者に明示的にするためだけに使用されることがありますが、実際には完全にオプションというわけではなく、インスタンス変数 (メンバー) と同じ名前の他の変数を区別する必要があります (メソッド内のローカル変数など)。
JavaScript はオブジェクト指向ですが、Java などの他のオブジェクト指向言語のようなクラスやメンバー メソッドはありません。JavaScript では、関数はオブジェクトの一種であり、一般的には、任意の変数またはオブジェクト プロパティを任意の関数を参照するように設定できます。質問。例:
function test1() {
alert('test1');
}
var obj1 = {
prop1 : 'obj1',
method1 : test1,
method2 : function() {
alert(this.prop1);
}
}
var test2 = obj1.method2;
obj1.method1(); // alerts 'test1'
test1(); // alerts 'test1'
obj1.method2(); // alerts 'obj1'
test2(); // alerts undefined (probably; see note below)
test2.call({prop1 : 'test2'}); // alerts 'test2'
delete obj1.method2; // remove the property
alert(obj1.method2); // alerts undefined - property no longer exists
test2.call({prop1 : 'test2'}); // alerts 'test2' - the function still exists
obj1.method1
リテラルの外で定義された関数、 で直接呼び出すことができる関数を参照していることに注意してくださいtest1()
。同様にtest2
、リテラルで定義されているが直接呼び出すことができる関数を参照するように設定されています。実際にmethod2
プロパティを削除しても、test2()
直接呼び出すことができます。
/を使用するようにmethod2
/を定義しました。の値は、関数の呼び出し方法に応じて設定されます。「ドット」表記で呼び出すと、関数内ではドットの前のオブジェクトになります。関数を直接呼び出すと、非厳密モードでは になりますが、厳密モードでは未定義またはその他の値になる可能性があります-詳細についてはMDNを参照してください。または、上記の例のように、 orを指定して関数を呼び出し、明示的に他のオブジェクトに設定することもできます。test2
this.prop1
this
obj1.method2()
this
test2()
this
window
.call()
.apply()
this