在JavaScript中的匿名函数中理解“this”

时间:2015-07-27 11:17:44

标签: javascript this anonymous-function

在这个post中,有很多答案在讨论JavaScript中的this关键字。但是,我仍然将this中的anonymous function混淆为

// 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与范围有关。 this的匿名函数中的MyModuleundefined。根据输出,函数A的一个范围是undefined,另一个是{ B: [Function: B], A: [Function: A] }。他们之间有什么区别?

2 个答案:

答案 0 :(得分:4)

this和范围几乎没有任何关系。在JavaScript中,this通常由函数调用的方式设置,而不是在其定义的位置。 (该规则有两个例外,我将在下面提到它们。)

因此,当您拨打A时,您正在设置呼叫期间this的内容(主要是隐式)。当你这样做时:

A();

...你正在调用A而没有做任何明确的事情来设置this应该是什么;因此,您隐式调用this设置为undefined,因为您的代码处于严格模式。 (如果它处于松散模式,你将调用它,并将this设置为对全局对象的引用。)同样值得注意的是,您正在通过创建的上下文解析标识符A通过调用您的匿名函数,其中包含AB作为(有效)变量。

但是在这里:

this.A();

...您正在调用A作为从对象属性(A获取函数引用的表达式的一部分;请注意,这是不同的含义A,但属性和上下文变量都引用相同的函数)。执行该操作的行为将A调用this设置为对您获取属性的对象的引用。

这就是为什么您在this中看到A的两个不同值。

this的例外情况由您调用它的方式设置”规则为:

  1. ES6的“箭头”功能,它从上下文(非范围)继承this

  2. ES5的“绑定”函数(在函数引用上调用.bind的结果),this调用将.bind括起来,所以总是看到this的值相同。

答案 1 :(得分:0)

通常,函数中的this绑定到您调用该函数的对象。

在你的例子中:

  • 您可以从输出中看到myModule.B()this等于myModule{ B: [Function: B], A: [Function: A] }
  • 然后,在try块内,您在没有对象的情况下调用A(),此处thisundefined,因为您在严格模式下运行 < / strong>,否则会指向全局对象,即浏览器中的window或节点中的global
  • 最后,最后一个电话是this.A(),此处您基本上将当前thismyModule)传递给该函数,因此它将是myModule

整个this绑定仅受您调用函数的方式的影响。