JavaScript では、これは必ずしもオブジェクト メソッドのコンテキストでのみ見つかるわけではなく、グローバル関数呼び出しや他のいくつかの異なるコンテキストでもこの参照が存在します。
グローバル オブジェクト、現在のオブジェクト、または任意のオブジェクトにすることができます。すべては関数の呼び出し方法によって異なります。 JavaScript で関数を呼び出す方法はいくつかあります。オブジェクト メソッドとして、関数として、コンストラクターとして、および apply または call を使用します。
1. オブジェクトメソッドとして呼び出します
JavaScriptでは関数もオブジェクトなので、関数をオブジェクトのメソッドと呼びますが、この呼び出しメソッドを使用すると、当然オブジェクトにバインドされます。
var point = {
x : 0、
y:0、
moveTo : function(x, y) {
This.x = this.x x
This.y = this.y y
}
};
point.moveTo(1, 1)//これは現在のオブジェクト、つまり point object
にバインドされます
2. 関数として呼び出す
関数は直接呼び出すこともできます。その場合、これはグローバル オブジェクトにバインドされます。ブラウザでは、ウィンドウはグローバル オブジェクトです。たとえば、次の例では、関数が呼び出されると、これがグローバル オブジェクトにバインドされ、代入ステートメントが実行されます。これは暗黙的にグローバル変数を宣言することと同じであり、呼び出し元が望んでいることではありません。
関数 makeNoSense(x) {
this.x = x;
}
makeNoSense(5);
x;// x は値 5 のグローバル変数になりました
内部関数、つまり別の関数本体で宣言された関数の場合、このグローバル オブジェクトへのバインド方法は別の問題を引き起こします。先ほど述べた point オブジェクトを例として取り上げますが、今回は、x 座標と y 座標をそれぞれ変換する 2 つの関数を moveTo メソッドに定義したいと考えています。結果は予期しないものになる可能性があります。点オブジェクトが移動しないだけでなく、さらに 2 つのグローバル変数 x と y が存在します。
var point = {
x : 0、
y:0、
moveTo : function(x, y) {
// 内部関数
var moveX = function(x) {
This.x = x;//これはどこにバインドされていますか?
};
// 内部関数
var moveY = function(y) {
This.y = y;//これはどこにバインドされていますか?
};
移動X(x);
移動Y(y);
}
};
point.moveTo(1, 1);
point.x; //==>0
point.y; //==>0
x; //==>1
y; //==>1
これは JavaScript の設計上の欠陥です。正しい設計方法は、内部関数の this をその外部関数に対応するオブジェクトにバインドすることです。この設計上の欠陥を回避するために、賢明な JavaScript プログラマーは変数置換を考え出しました。メソッドでは、慣例により、変数には通常その名前が付けられます。
コードをコピー
y : 0、
moveTo : function(x, y) {
var that = これ;
// 内部関数
var moveX = function(x) {
それ.x = x;
};
// 内部関数
var moveY = function(y) {
それ。y = y;
}
移動X(x);
移動Y(y);
}
};
point.moveTo(1, 1);
point.x; //==>1
point.y; //==>1
コンストラクターとして呼び出す
JavaScript はオブジェクト指向プログラミングをサポートしています。主流のオブジェクト指向プログラミング言語とは異なり、JavaScript にはクラスの概念がありませんが、プロトタイプに基づく継承が使用されます。これに対応して、JavaScript のコンストラクターも非常に特殊であり、new で呼び出されない場合は、通常の関数と同じになります。もう 1 つの規則として、コンストラクターは呼び出し元に正しい方法で呼び出すことを思い出させるために大文字で始まります。正しく呼び出された場合、これは新しく作成されたオブジェクトにバインドされます。
関数 Point(x, y){
これ.x = x;
これ.y = y;
}
電話をかけるには、apply または call を使用してください
JavaScript では関数もオブジェクトであり、オブジェクトには関数オブジェクトのメソッドである apply メソッドと call メソッドがあることをもう一度繰り返します。これら 2 つのメソッドは非常に強力で、関数が実行されるコンテキスト、つまり関数がバインドされているオブジェクトを切り替えることができます。 JavaScript の多くのテクニックやライブラリでこのメソッドが使用されています。具体的な例を見てみましょう:
関数 Point(x, y){
これ.x = x;
これ.y = y;
This.moveTo = function(x, y){
これ.x = x;
これ.y = y;
}
}
var p1 = 新しいポイント(0, 0)
var p2 = {x: 0, y: 0};
p1.moveTo(1, 1);
p1.moveTo.apply(p2, [10, 10]);
上記の例では、コンストラクターを使用してオブジェクト p1 を生成し、このオブジェクトには moveTo メソッドもあります。オブジェクト リテラルを使用して別のオブジェクト p2 を作成し、apply を使用して p1 のメソッドを p2 に適用できることがわかります。 、今回はこれもオブジェクト p2 にバインドされます。別のメソッド呼び出しにも同じ機能がありますが、最後のパラメータが配列として均一に渡されるのではなく、個別に渡される点が異なります。
コードをコピー
コードは次のとおりです:
if(this==ウィンドウ){
alert('通常の通話');
}
それ以外の場合は、他のオブジェクトのメソッドとして呼び出されます
alert('this.constructor によって呼び出されました);
}
}
Foo();//グローバル関数呼び出し
Foo.call(new Object());//オブジェクト object のメンバー メソッドとして呼び出します
new Foo();//オブジェクト構築を実行するために new 演算子によって呼び出されます