簡體   English   中英

了解JavaScript匿名函數中的“ this”

[英]Understanding “this” within anonymous function in JavaScript

在這個崗位 ,很多答案都在那里討論this在JavaScript中的關鍵字。 但是,我仍然在anonymous function this感到困惑,如下所示

// MyModule.js
'use strict';
(function(handler) {
    // export methods
    handler.B = B;
    handler.A = A;

    function A() {
        console.log(this);
        console.log('function A is invoked...');
    }

    function B() {
        console.log(this);
        console.log('function B is invoked...');
        try {
            A();
            this.A();
        } catch (err) {
            console.log('Exception is ' + err);
        }
    }
})(module.exports);

// test.js
var myModule = require('MyModule.js');
myModule.B();

輸出:(在Node.js下運行)

{ B: [Function: B], A: [Function: A] }
function B is invoked...

undefined
function A is invoked...

{ B: [Function: B], A: [Function: A] }
function A is invoked...

輸出表明函數A在兩個不同的范圍內。 我對嗎? 為什么函數A有兩個作用域?

眾所周知, this與范圍有關。 並且MyModule匿名函數中的thisundefined 根據輸出,函數A的范圍之一是undefined ,另一個是{ B: [Function: B], A: [Function: A] } 它們之間有什么區別?

this和范圍幾乎沒有任何關系。 在JavaScript中, this通常是由設置的功能如何被調用 ,而不是在那里的定義。 (該規則有兩個例外,我將在下面提及它們。)

所以,當你調用A ,你設置什么this將是調用(主要是隱含的)期間。 執行此操作時:

A();

......你調用A沒有做任何明確的設置什么this是應該的; 其結果是,你是隱式調用它this設置為undefined ,因為你的代碼是嚴格模式。 (如果它是松散的模式,你可以用它調用this設置為全局對象的引用。)這也是值得注意的是,你解決標識A經通過調用創建您的匿名函數的情況下,包含AB作為(有效)變量。

但在這兒:

this.A();

...您正在調用A作為從對象屬性獲取函數引用的表達式的一部分( A ;請注意,這對A不同的含義,但是屬性和上下文變量都引用同一函數)。 這樣做的行為要求Athis設置為你從得到的屬性的對象的引用。

這就是為什么你看到兩個不同的值thisA

this是通過您的調用方式設置的”規則的例外情況是:

  1. ES6的“箭頭”的功能,它繼承了this從他們創造文意 (未范圍)。

  2. ES5的“綁定”功能(調用的結果.bind上的功能參考),已經this被烤成他們.bind呼叫,所以總是看到相同的值this

通常, this函數在函數中綁定到調用該函數的對象。

在您的示例中:

  • 您可以調用myModule.B()this等於myModule ,從輸出中可以看到: { B: [Function: B], A: [Function: A] }
  • 然后,在try塊內調用不帶對象的A()thisundefined因為您正在嚴格模式下運行,否則它將指向全局對象 ,該對象是瀏覽器中的window或節點中的global
  • 最后,最后一個調用是this.A() ,這里您基本上是將當前的thismyModule )傳遞給函數,因此它將是myModule

整個this綁定僅受調用函數的方式影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM