Understanding “this” within anonymous function in JavaScript

旧城冷巷雨未停 提交于 2021-01-28 00:33:47

问题


In this post, lots of answers are there discussing the this keyword in JavaScript. However, I am still confuse this in the anonymous function as following

// 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)

{ 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. Am I right? Why there are two scopes for function A?

As we know, the this is related to the scope. And the this in the anonymous function of MyModule is undefined. According to the output, one of the scope of function A is undefined, the other is { B: [Function: B], A: [Function: A] }. What the difference between them?


回答1:


this and scope have almost nothing to do with each other. In JavaScript, this is usually set by how a function is called, not where it's defined. (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). When you do this:

A();

...you're calling A without doing anything explicit to set what this should be; as a result, you're implicitly calling it with this set to undefined, because your code is in strict mode. (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.

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). The act of doing that calls A with this set to a reference to the object you got the property from.

That's why you see two different values for this in A.

The exceptions to the "this is set by how you call it" rule are:

  1. ES6's "arrow" functions, which inherit this from the context (not scope) where they're created.

  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.




回答2:


Usually, this, in a function, is bound to the object on which you called that function.

In your example:

  • You call myModule.B(), this equals to myModule, as you can see from the output: { 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
  • Finally, the last call is this.A(), here you're basically passing your current this (myModule) to the function, so it will be myModule.

The whole this binding is affected only by the way you call a function.



来源:https://stackoverflow.com/questions/31651685/understanding-this-within-anonymous-function-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!