JavaScript での this の意味は、実行時バインディング機能により、より豊富になります。グローバル オブジェクト、現在のオブジェクト、または任意のオブジェクトにすることができ、すべては関数の呼び出し方法によって異なります。 JavaScript で関数を呼び出す方法はいくつかあります。オブジェクト メソッドとして、関数として、コンストラクターとして、および apply または call を使用します。以下では、さまざまな呼び出し方法に応じて、これの意味をそれぞれ説明します。
JavaScriptでは関数もオブジェクトなので、この呼び出しメソッドを使用する場合、関数はオブジェクトのメソッドとして呼び出されます。これは自然にオブジェクトにバインドされます。
1
2
3
4
5
6
7
8 9
10
|
var point = { var point = {
x : 0, y : 0, moveTo : function(x, y) { this.x = this.x + x;
this.y = this.y + y;
}
}; point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象 |
函数也可以直接被调用,此时 this 绑定到全局对象。在浏览器中,window 就是该全局对象。比如下面的例子:函数被调用时,this 被绑定到全局对象,接下来执行赋值语句,相当于隐式的声明了一个全局变量,这显然不是调用者希望的。
1
2
3
4
5
6
|
function makeNoSense(x) { this.x = x; } makeNoSense(5); x;// x 已经成为一个值为 5 的全局变量 x : 0,
|
this.x = this.x + x;
🎜🎜
this.y = this.y + y ;
🎜🎜
}
🎜🎜}; >🎜🎜 🎜🎜<code class="htmlscript plain">point.moveTo(1, 1)//これは現在のオブジェクト、つまり point オブジェクトにバインドされます
🎜🎜🎜🎜🎜🎜🎜🎜関数としての 🎜🎜 呼び出し元の 🎜🎜 関数は直接呼び出すこともでき、その場合、これはグローバル オブジェクトにバインドされます。ブラウザでは、ウィンドウはグローバル オブジェクトです。たとえば、次の例では、関数が呼び出されると、これがグローバル オブジェクトにバインドされ、代入ステートメントが実行されます。これは暗黙的にグローバル変数を宣言することと同じであり、呼び出し元が望んでいることではありません。 🎜🎜リスト 3. nonsense.js🎜🎜🎜🎜🎜🎜🎜🎜🎜1🎜🎜2🎜🎜3🎜🎜4🎜🎜5🎜🎜6🎜🎜🎜🎜🎜関数 makeNoSense ( x) { 🎜🎜this.x = x
🎜🎜}
🎜🎜 🎜🎜makeNoSense(5); 🎜🎜x;// x は値 5 のグローバル変数になりました
🎜🎜🎜 🎜🎜🎜内部関数、つまり別の関数の本体で宣言された関数の場合、このグローバル オブジェクトへのバインド方法は別の問題を引き起こします。先ほど述べた point オブジェクトを例として取り上げますが、今回は、x 座標と y 座標をそれぞれ変換する 2 つの関数を moveTo メソッドに定義したいと考えています。結果は予想外になる可能性があります。ポイント オブジェクトが移動しないだけでなく、さらに 2 つのグローバル変数 x と y が存在します。
1
2
3
4
5
6
7
8 9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
var point = { <code class="htmlscript plain">var point = { x : 0, y : 0, moveTo : function(x, y) { // 内部函数
var moveX = function(x) {
this.x = x;//this 绑定到了哪里?
};
// 内部函数
var moveY = function(y) {
this.y = y;//this 绑定到了哪里?
};
moveX(x);
moveY(y);
}
}; point.moveTo(1, 1); point.x; //==>0 point.y; //==>0 x; //==>1 y; //==>1 x : 0,
|
// 内部関数
🎜🎜 var moveX = function(x) {
🎜🎜
this.x = x;//これはどこにバインドされていますか?
🎜🎜
}
🎜🎜
// 内部関数🎜🎜
var moveY = function(y) {
code>var moveY = function(y) {
code>🎜🎜
this .y = y;//これはどこにバインドされていますか?
🎜🎜
}
🎜🎜🎜🎜
moveX(x);
🎜🎜
moveY(y); code> code>🎜🎜<code class="htmlscript space">
}
🎜🎜}; 🎜🎜 <code class="htmlscript plain">point.moveTo(1, 1)
🎜🎜point.x; 🎜🎜 <code class="htmlscript plain">point.y //==>0
🎜🎜//==>1
; 🎜🎜 y //==>1
🎜🎜🎜🎜🎜🎜;
これは JavaScript の設計上の欠陥です。正しい設計方法は、この設計上の欠陥を回避するために、内部関数の this をその外部関数に対応するオブジェクトにバインドすることです。置換メソッドでは、慣例により、変数には通常その名前が付けられます。
1
2
3
4
5
6
7
8 9
10
11
12
13
14
16
17
18
19
20
|
plainvar point = { x : 0,
var point = {
x : 0, y : 0, moveTo : function(x, y) { var that = this;
// 内部函数
var moveX = function(x) {
that.x = x;
};
// 内部函数
var moveY = function(y) {
that.y = y;
}
moveX(x);
moveY(y);
}
}; point.moveTo(1, 1); point.x; //==>1 point.y; //==>1 y : 0,
|
// 内部関数
🎜🎜
var moveX = function(x) {
🎜🎜
that.x = x
🎜🎜
};
🎜🎜
// 内部function
🎜🎜
var moveY = function(y) {
🎜🎜
that.y = y;
🎜🎜
}
🎜🎜
moveX(x)
🎜🎜
code>moveY(y);
🎜🎜
}
🎜 🎜}
🎜🎜point.moveTo(1, 1);
🎜🎜point.x; //==>1
🎜🎜point.y;
JavaScript は、主流のオブジェクト指向プログラミング言語とは異なり、クラスの概念を持たず、プロトタイプに基づく継承を使用します。これに対応して、JavaScript のコンストラクターも非常に特殊であり、new で呼び出されない場合は通常の関数と同じです。もう 1 つの規則として、コンストラクターは呼び出し元に正しい方法で呼び出すことを思い出させるために大文字で始まります。正しく呼び出された場合、これは新しく作成されたオブジェクトにバインドされます。
1
2
3
4
|
function Point(x, y){ <code class="htmlscript plain">function Point(x, y){ this.x = x;
this.y = y;
} |
让我们再一次重申,在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。很多 JavaScript 中的技巧以及类库都用到了该方法。让我们看一个具体的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function Point(x, y){ this.x = x;
this.y = y;
this.moveTo = function(x, y){
this.x = x;
this.y = y;
}
} var p1 = new Point(0, 0); var p2 = {x: 0, y: 0}; p1.moveTo(1, 1); p1.moveTo.apply(p2, [10, 10]); this.x = x
|
関数 Point(x, y){
🎜🎜
this.x = x;
🎜🎜
this.y = y; ="htmlscript space">
this.moveTo = function(x, y){
🎜 <code class="htmlscript plain">this.y = y;
🎜
}
🎜p1.moveTo(1 , 1);
🎜p1.moveTo.apply(p2, [10, 10]);
🎜🎜 🎜 🎜🎜🎜🎜🎜🎜🎜 上の例では、コンストラクターを使用してオブジェクト p1 を生成し、これには moveTo メソッドもあります。オブジェクト リテラルを使用して別のオブジェクト p2 を作成すると、apply を使用して p1 を移動できることがわかります。このとき、これもオブジェクト p2 にバインドされます。別のメソッド呼び出しにも同じ機能がありますが、最後のパラメータが配列として均一に渡されるのではなく、個別に渡される点が異なります。 🎜以上がこれについてjsで詳しく説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。