このキーワードを深く説明する
4310 ワード
pythonなどの他のプログラミング言語に比べて、JavaScriptでのthisキーワードの表現は異なり、厳格なモードかどうかもthisのバインドに影響します.この中にはいろいろな方法があり、うっかりすると間違いになる可能性があります.そして、thisはダイナミックな役割ドメインのいとことして、JavaScriptの文法の役割ドメインとは大きく異なるので、JavaScriptの大きな穴と呼ばれています.(私もそう思います、2333)
ほとんどの場合、関数の呼び出し方法はthisの値を決定します.thisは実行中に値を割り当てることができず、関数が呼び出されるたびにthisの値が異なる場合があります.ここでは主に,ES 6における矢印関数におけるいくつかの一般的な呼び出し方式とthisについて議論する.
いくつかの一般的な呼び出し方法:
1.グローバル範囲でthisを使用すると、グローバルオブジェクトであるwindowを指します.
2.関数で呼び出されると、グローバルオブジェクトも指します.nodeではglobalを指します.
ES 5の厳密なモードでは、グローバル変数は存在しないことに注意してください.thisは、実行コンテキストに入ったときの値を保持します.この場合、thisはundefinedになります.
3.メソッド呼び出しtext.foo(); この例ではthisはtextオブジェクトを指します.このような動作は、関数の定義方法や位置の影響を受けないことに注意してください.このバインドは、最も近いメンバー参照の影響のみを受けます.
4.コンストラクション関数として使用される関数のthisは、コンストラクション中の新しいオブジェクトにバインドされます.
5.callメソッドまたはapplyメソッドを使用すると、関数内のthisは、関数呼び出しの最初のパラメータとして明示的に設定されます.
callとapply関数を使用する場合は、thisに渡される値がオブジェクトでない場合、JavaScriptは内部ToObject操作を使用してオブジェクトに変換しようとします.
6.objを呼び出す.bind()ではobjと同じ関数体と役割ドメインを持つ関数を作成できますが、この関数がどのように呼び出されてもbindの最初のパラメータに永続的にバインドされます.
7.プロトタイプチェーンのthisは、呼び出されたオブジェクトを指しています.これは理解しやすいです.
8.関数がイベント処理関数として使用される場合、thisはイベントをトリガーする要素を指します.
矢印関数
この複雑さのため、JavaScriptで最もエラーが発生する要因の一つとなっています.したがって、ES 6の矢印関数にはthisバインドがありません.役割ドメインチェーンを検索して値を決定する必要があります.グローバルコードでは、グローバルオブジェクトとして設定されます.
矢印関数はthisをバインドしないため、call()/apply()/bind()メソッドは矢印関数にとって入力パラメータにすぎず、thisには影響しません.
thisが文法的な面であることを考慮すると,厳格なモードではthisに関連する規則は無視される.(厳密モードでの影響は無視できます)
矢印関数をメソッドとして呼び出すと、thisはどうなりますか?
メソッドとしての矢印関数thisはグローバルオブジェクト(window)を指し、通常の関数のthisは呼び出したオブジェクトを指します.
ほとんどの場合、関数の呼び出し方法はthisの値を決定します.thisは実行中に値を割り当てることができず、関数が呼び出されるたびにthisの値が異なる場合があります.ここでは主に,ES 6における矢印関数におけるいくつかの一般的な呼び出し方式とthisについて議論する.
いくつかの一般的な呼び出し方法:
1.グローバル範囲でthisを使用すると、グローバルオブジェクトであるwindowを指します.
var a = 1;
console.log(this.a); // 1
console.log(this === window); // true
this.b = "hello,world";
console.log(window.b); // "hello,world"
console.log(b); // "hello,world"
2.関数で呼び出されると、グローバルオブジェクトも指します.nodeではglobalを指します.
var a = 1;
function fn(){
var a = 2;
console.log(a);
}
fn(); //1
// :
// :
fn() === window;
// Node :
fn() === global;
ES 5の厳密なモードでは、グローバル変数は存在しないことに注意してください.thisは、実行コンテキストに入ったときの値を保持します.この場合、thisはundefinedになります.
"use strict"
function fn(a){
console.log(this);
}
fn(1); //undefined
fn() === undefined; // true
3.メソッド呼び出しtext.foo(); この例ではthisはtextオブジェクトを指します.このような動作は、関数の定義方法や位置の影響を受けないことに注意してください.このバインドは、最も近いメンバー参照の影響のみを受けます.
var text = {
num: 1,
foo: function() {
return this.num;
}
};
console.log(text.foo()); // 1
fn = text.foo;
text.a = {b: fn, num: 2};
console.log(text.a.b()); // 2
4.コンストラクション関数として使用される関数のthisは、コンストラクション中の新しいオブジェクトにバインドされます.
function Person(age){
this.age = age;
}
var jake = new Person(18);
jake.age; //18
5.callメソッドまたはapplyメソッドを使用すると、関数内のthisは、関数呼び出しの最初のパラメータとして明示的に設定されます.
// call apply , this
var obj = {a: 1};
// global 。
var a = 2;
function fn() {
// this
return this.a;
}
fn(); // 2
fn.call(obj); // 1
fn.apply(obj); // 1
callとapply関数を使用する場合は、thisに渡される値がオブジェクトでない場合、JavaScriptは内部ToObject操作を使用してオブジェクトに変換しようとします.
6.objを呼び出す.bind()ではobjと同じ関数体と役割ドメインを持つ関数を作成できますが、この関数がどのように呼び出されてもbindの最初のパラメータに永続的にバインドされます.
var obj = {name: 'Jake'};
function sayName(){
console.log(this.name)
};
var fn = sayName.bind(obj);
// fn
// sayName , this obj
fn() // : 'Jake'
7.プロトタイプチェーンのthisは、呼び出されたオブジェクトを指しています.これは理解しやすいです.
var fn = {
add : function(){
return this.a + this.b;
}
};
var p = Object.create(fn);
p.a = 1;
p.b = 2;
console.log(p.add()); // 3
8.関数がイベント処理関数として使用される場合、thisはイベントをトリガーする要素を指します.
// ,
function bluify(e){
//
console.log(this);
//
e.stopPropagation();
//
e.preventDefault();
this.style.backgroundColor = '#A5D9F3';
}
//
var elements = document.getElementsByTagName('*');
// bluify , ,
for(var i=0 ; i
矢印関数
この複雑さのため、JavaScriptで最もエラーが発生する要因の一つとなっています.したがって、ES 6の矢印関数にはthisバインドがありません.役割ドメインチェーンを検索して値を決定する必要があります.グローバルコードでは、グローバルオブジェクトとして設定されます.
var obj = this;
var foo = (() => this);
console.log(foo() === obj); // true
矢印関数はthisをバインドしないため、call()/apply()/bind()メソッドは矢印関数にとって入力パラメータにすぎず、thisには影響しません.
//
var a = {foo: foo};
console.log(a.foo() === obj); // true
// call this
console.log(foo.call(a) === obj); // true
// call this
foo = foo.bind(a);
console.log(foo() === obj); // true
thisが文法的な面であることを考慮すると,厳格なモードではthisに関連する規則は無視される.(厳密モードでの影響は無視できます)
var a = () => {'use strict'; return this};
var b = () => { return this};
console.log(1,a() === window);
console.log(2,a() === b());
//1 true
//2 true
矢印関数をメソッドとして呼び出すと、thisはどうなりますか?
var obj = {
a: 1,
b: () => console.log(this.a, this),
c: function() {
console.log( this.a, this)
}
}
obj.b(); // undefined Window{postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window,…}
obj.c(); // 1 {a: 1, b: ƒ, c: ƒ}
メソッドとしての矢印関数thisはグローバルオブジェクト(window)を指し、通常の関数のthisは呼び出したオブジェクトを指します.