“理解”;这";JavaScript中的匿名函数内

“理解”;这";JavaScript中的匿名函数内,javascript,this,anonymous-function,Javascript,This,Anonymous Function,在这篇文章中,很多答案都在讨论JavaScript中的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 i

在这篇文章中,很多答案都在讨论JavaScript中的
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下运行)

输出表明功能
A
在两个不同的范围内。我说得对吗?为什么函数
A有两个作用域


我们知道,
这个
与范围相关。而
MyModule
的匿名函数中的
this
undefined
。根据输出,函数
A
的一个范围是
未定义的
,另一个范围是
{B:[函数:B],A:[函数:A]}
。它们之间的区别是什么?

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

因此,当您调用
A
时,您正在设置调用期间该
将是什么(大部分是隐式的)。执行此操作时:

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

但在这里:

this.A();
…您正在调用
A
,作为从对象属性获取函数引用的表达式的一部分(
A
;请注意,这与
A
的含义不同,但属性和上下文变量都引用同一个函数)。这样做会调用
A
,并将
this
设置为对从中获取属性的对象的引用

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

由您如何称呼它”规则的例外情况如下:

  • ES6的“arrow”函数,它从创建它们的上下文(而不是范围)继承

  • ES5的“绑定”函数(在函数引用上调用
    .bind
    的结果),这些函数通过
    .bind
    调用将
    烘焙到它们中,因此总是可以看到
    的相同值


  • 通常,
    在函数中绑定到调用该函数的对象

    在您的示例中:

    • 您调用
      myModule.B()
      等于
      myModule
      ,从输出中可以看到:
      {B:[函数:B],A:[函数:A]}
    • 然后,在没有对象的情况下调用
      try
      块中
      A()
      ,这里
      这个
      未定义的
      ,因为你在严格模式下运行,否则它会指向全局对象,在浏览器中是
      窗口
      ,在节点中是
      全局
    • 最后,最后一个调用是
      this.A()
      ,这里基本上是将当前的
      this
      myModule
      )传递给函数,因此它将是
      myModule

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

    不是两个不同的作用域,两个不同的上下文,也不是相同的
    。在sitenote上,“使用严格”应该在匿名函数中。@koningdavid:在这里也可以,如果不需要在全局范围内使用
    来获取全局对象,则上面的代码不需要。
    this.A();