问题
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:
ES6's "arrow" functions, which inherit
this
from the context (not scope) where they're created.ES5's "bound" functions (the result of calling
.bind
on a function reference), which havethis
baked into them by the.bind
call and so always see the same value forthis
.
回答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 tomyModule
, as you can see from the output:{ B: [Function: B], A: [Function: A] }
- Then, inside the
try
block you callA()
without an object, herethis
isundefined
because you're running in strict mode, otherwise it would point to the global object, which iswindow
in a browser orglobal
in node - Finally, the last call is
this.A()
, here you're basically passing your currentthis
(myModule
) to the function, so it will bemyModule
.
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