これにどのようなルールがあるかを判断したい場合は、これが関数内にあるものを判断するためのルールがいくつかあります。これが何であるかを判断するのは実際には非常に簡単です。一般的なルールは、関数が呼び出されたときに、その関数が呼び出された場所を確認することによってこれを判断することです。次に優先順位に従って説明するルールに従います。
ルール
1. 関数を呼び出すときに new キーワードを使用すると、関数内の this はまったく新しいオブジェクトになります。
function ConstructorExample() { console.log(this); this.value = 10; console.log(this); } new ConstructorExample(); // -> {} // -> { value: 10 }
2. apply、call、bind を使用して関数を呼び出す場合、関数内の this はパラメーターとして渡されるオブジェクトです。
function fn() { console.log(this); } var obj = { value: 5 }; var boundFn = fn.bind(obj); boundFn(); // -> { value: 5 } fn.call(obj); // -> { value: 5 } fn.apply(obj); // -> { value: 5 }
3. 関数がメソッドとして呼び出された場合、つまり、関数がドット表記を使用して呼び出された場合、これはこの関数を属性として持つオブジェクトです。つまり、ポイントが関数呼び出しの左側にある場合、これはポイントの左側にあるオブジェクトになります。
var obj = { value: 5, printThis: function() { console.log(this); } }; obj.printThis(); // -> { value: 5, printThis: ƒ }
4. 関数が純粋関数として呼び出された場合、つまり上記の条件を何も指定せずに呼び出された場合、これはグローバル オブジェクトです。ブラウザでは、これはウィンドウ オブジェクトです。
function fn() { console.log(this); } // 如果在浏览器里调用: fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
このルールは実際には 3 番目のルールと同じであることに注意してください。違いは、メソッドとして宣言されていない関数が自動的にグローバル オブジェクト ウィンドウの属性になることです。したがって、これは実際には暗黙的なメソッド呼び出しです。 fn() を呼び出すと、実際にはブラウザによって window.fn() として認識されるため、これは window です。
console.log(fn === window.fn); // -> true
5. 上記のルールが複数当てはまる場合、優先度の高いルールがこの値を設定します。
6. ES2015 のアロー関数の場合、上記のルールをすべて無視し、作成時にそれを含むスコープを this の値として受け取ります。これが何であるかを判断するには、アロー関数を作成した場所から 1 行上に移動し、アロー関数内の this の値が同じであることを確認します。
const obj = { value: 'abc', createArrowFn: function() { return () => console.log(this); } }; const arrowFn = obj.createArrowFn(); arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }
3 番目のルールを振り返ると、obj.createArrowFn() を呼び出すと、これはメソッド呼び出しであるため、createArrowFn の this は obj になります。したがって、obj は arrowFn でこれにバインドされます。グローバル スコープでアロー関数を作成すると、この値は window になります。
ルールの適用
コード例を見て、これらのルールを適用してみましょう。試してみて、さまざまな関数呼び出しでこれが何であるかを理解できるかどうかを確認してください。
適用されるルールを決定する
var obj = { value: 'hi', printThis: function() { console.log(this); } }; var print = obj.printThis; obj.printThis(); // -> {value: "hi", printThis: ƒ} print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
obj.printThis() は 3 番目のルールであるメソッド呼び出しに属します。一方、print() は 4 番目のルールである純粋な関数呼び出しに該当します。 print() の場合、呼び出し時に new、bind/call/apply、またはドット表記を使用しなかったので、これはルール 4 に相当し、これはグローバル オブジェクト ウィンドウです。
複数のルールが適用される場合
複数のルールが適用される場合は、リスト内で優先度の高いルールを使用します。
var obj1 = { value: 'hi', print: function() { console.log(this); }, }; var obj2 = { value: 17 };
ルール 2 とルール 3 が同時に適用される場合は、ルール 2 が優先されます。
obj1.print.call(obj2); // -> { value: 17 }
ルール 1 とルール 3 が同時に適用される場合、ルール 1 が優先されます。
new obj1.print(); // -> {}
ライブラリ
一部のライブラリは、この値を意図的に特定の関数にバインドすることがあります。通常、最も有用な値は関数内でこれにバインドされます。たとえば、jQuery はこれを DOM 要素にバインドし、コールバックでイベントをトリガーします。ライブラリの this 値が上記の規則に準拠していない場合は、bind を使用してバインドされている可能性がありますので、ライブラリのドキュメントをよく読んでください。
このオブジェクトは、関数の実行時に関数の実行環境に基づいてバインドされます。 js でのこのオブジェクトの使用法の詳細な分析を紹介します。実際、この文の本質は、関数を呼び出す人が誰を指すかということです
具体的には、通常、次のような状況があります。グローバル関数
グローバル環境では、これは Window を指します
//例子1 function A() { console.log(this) } A();//Window
上の例は非常に単純です。関数 A はグローバル環境で実行されます。つまり、グローバル オブジェクト Window が関数を呼び出します。このとき、これはWindow
オブジェクトのメソッドを指します
オブジェクトメソッドとして呼び出された場合は、メソッドを呼び出すオブジェクトを指します
//例子2 var b = { getThis:function(){ console.log(this) } } b.getThis()//b
これまで挙げた例は比較的シンプルで分かりやすいものです。次は興味深いものです:
//例子3 var c = { getFunc:function(){ return function(){ console.log(this) } } } var cFun = c.getFunc() cFun()//Window
この例は、c.getFunc() を実行すると、最初にこの関数を cFun に割り当ててから、グローバルで cFun() を呼び出します。環境なので、この時点では Or Window を指します。
ここで c オブジェクトを返さなければならない場合はどうすればよいでしょうか?冒頭で、 this オブジェクトは関数の実行時に決定されると述べましたが、 c.getFunc() が実行されるとき、 this オブジェクトは依然として c を指しているため、上記では this を保持するだけで済みます。コードは少し変更されています:
//例子4 var c = { getFunc:function(){ var that = this //在这里保留住this return function(){ console.log(that) } } } var cFun = c.getFunc() cFun()//c
これが、一部のコードで var self = this または var that = this がよく見られる理由です。
call と apply
この時点で、this オブジェクトは通常、関数で指定された this 値を指します (通常、ここに 2 つの単語が含まれていることに注意してください。試験でテストされます)
call と apply は決まり文句ですが、新入生を恐れるため、簡単に紹介します (実際には単語を作るためだけです)。call を例に挙げると、構文は次のとおりです
fun.call(thisArg, arg1, arg2, ...)
このメソッドの使用方法、以下の例を見てください:
//例子5 var d = { getThis:function(){ console.log(this) } } var e = { name:'e'//(给e写个`name`属性只是因为觉得孤零零的太难看了~~) } d.getThis.call(e)//e
在这里我们就可以看出call函数的意思了:指定一个对象o1去调用其他对象o2的方法,此时this对象指向o1
好了,那为什么前面我们说通常呢?因为,这里的thisArg是可以指定为null和undefined的。请看:
//例子6 var d = { getThis:function(){ console.log(this) } } d.getThis.call(null)//Window d.getThis.call(undefined)//Window
此时的this指向全局对象Window
箭头函数
es6中的箭头函数现在也用的比较频繁,但是有个需要注意的点是:
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
其实出现这种情况的根本原因是:箭头函数没有this对象,所以箭头函数的this就是外层代码的this
//例子7 var f = { getThis:()=>{ console.log(this) } } f.getThis()//Window
这个例子和前面例子2是基本一样的,只是把普通函数改写成箭头函数,但是此时的this对象已经指向了外层的Window。
考虑到这一点可能不好理解,我们再看几个例子:
//例子8 var g = { getThis:function(){ return function(){console.log(this)} } } var h = { getThis:function(){ return ()=> console.log(this) } } g.getThis()()//Window h.getThis()()//h
这个例子里,g的getThis写法就和之前的例子3一样,由于函数在全局环境中运行,所以此时this指向Window;h的getThis使用了箭头函数,所以this指向了外层代码块的this所以,此时this指向的是h。
总结
一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向Window
在call和apply函数中this指向指定的对象,如果指定的对为undefined或者null,那么this对象指向Window
在箭头函数中,this对象等同于外层代码块的this。
相关推荐:
以上がJavaScript でのこのルールとこのオブジェクトの使用例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。