简体   繁体   English

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

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

In this post , lots of answers are there discussing the this keyword in JavaScript. 在这个岗位 ,很多答案都在那里讨论this在JavaScript中的关键字。 However, I am still confuse this in the anonymous function as following 但是,我仍然在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();

Output: (Running under Node.js) 输出:(在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...

The output indicates the function A are in two different scopes. 输出表明函数A在两个不同的范围内。 Am I right? 我对吗? Why there are two scopes for function A ? 为什么函数A有两个作用域?

As we know, the this is related to the scope. 众所周知, this与范围有关。 And the this in the anonymous function of MyModule is undefined . 并且MyModule匿名函数中的thisundefined According to the output, one of the scope of function A is undefined , the other is { B: [Function: B], A: [Function: A] } . 根据输出,函数A的范围之一是undefined ,另一个是{ B: [Function: B], A: [Function: A] } What the difference between them? 它们之间有什么区别?

this and scope have almost nothing to do with each other. this和范围几乎没有任何关系。 In JavaScript, this is usually set by how a function is called , not where it's defined. 在JavaScript中, this通常是由设置的功能如何被调用 ,而不是在那里的定义。 (There are two exceptions to that rule, I'll mention them below.) (该规则有两个例外,我将在下面提及它们。)

So when you're calling A , you're setting what this will be during the call (largely implicitly). 所以,当你调用A ,你设置什么this将是调用(主要是隐含的)期间。 When you do this: 执行此操作时:

A();

...you're calling A without doing anything explicit to set what this should be; ......你调用A没有做任何明确的设置什么this是应该的; as a result, you're implicitly calling it with this set to undefined , because your code is in strict mode. 其结果是,你是隐式调用它this设置为undefined ,因为你的代码是严格模式。 (If it were in loose mode, you'd be calling it with this set to a reference to the global object.) It's also worth noting that you're resolving the identifier A via the context created by the call to your anonymous function, which contains A and B as (effectively) variables. (如果它是松散的模式,你可以用它调用this设置为全局对象的引用。)这也是值得注意的是,你解决标识A经通过调用创建您的匿名函数的情况下,包含AB作为(有效)变量。

But here: 但在这儿:

this.A();

...you're calling A as part of an expression getting the function reference from an object property ( A ; note that this is a different meaning for A , but that both the property and the context variable refer to the same function). ...您正在调用A作为从对象属性获取函数引用的表达式的一部分( A ;请注意,这对A不同的含义,但是属性和上下文变量都引用同一函数)。 The act of doing that calls A with this set to a reference to the object you got the property from. 这样做的行为要求Athis设置为你从得到的属性的对象的引用。

That's why you see two different values for this in A . 这就是为什么你看到两个不同的值thisA

The exceptions to the " this is set by how you call it" rule are: this是通过您的调用方式设置的”规则的例外情况是:

  1. ES6's "arrow" functions, which inherit this from the context (not scope) where they're created. ES6的“箭头”的功能,它继承了this从他们创造文意 (未范围)。

  2. ES5's "bound" functions (the result of calling .bind on a function reference), which have this baked into them by the .bind call and so always see the same value for this . ES5的“绑定”功能(调用的结果.bind上的功能参考),已经this被烤成他们.bind呼叫,所以总是看到相同的值this

Usually, this , in a function, is bound to the object on which you called that function. 通常, this函数在函数中绑定到调用该函数的对象。

In your example: 在您的示例中:

  • You call myModule.B() , this equals to myModule , as you can see from the output: { B: [Function: B], A: [Function: A] } 您可以调用myModule.B()this等于myModule ,从输出中可以看到: { B: [Function: B], A: [Function: A] }
  • Then, inside the try block you call A() without an object, here this is undefined because you're running in strict mode , otherwise it would point to the global object , which is window in a browser or global in node 然后,在try块内调用不带对象的A()thisundefined因为您正在严格模式下运行,否则它将指向全局对象 ,该对象是浏览器中的window或节点中的global
  • Finally, the last call is this.A() , here you're basically passing your current this ( myModule ) to the function, so it will be myModule . 最后,最后一个调用是this.A() ,这里您基本上是将当前的thismyModule )传递给函数,因此它将是myModule

The whole this binding is affected only by the way you call a function. 整个this绑定仅受调用函数的方式影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM