Reputation: 291
In an arrow function there is no this binding. So, arrow functions lexically resolve this reference. If we execute a function in different scope from where the function was defined, it remembers this reference. Does this behaviour happens due to closure ?
I know that function can remember its lexical environment by closure but in chrome developer tool this doesnot appear in closure but in local scope. Why does this happens ?
function outerScope(outerVar){
let innerFun = () =>{
console.log(outerVar);
console.log(this);
}
return innerFun;
}
let innerFun = outerScope.call({test: "testing this reference"},"outerVar");
innerFun();
Upvotes: 0
Views: 184
Reputation: 29087
Does this behaviour happens due to closure ?
No
Your statement implies it's a side-effect of other mechanisms. It is deliberately part of the specification.
Section 14.2 Arrow Function Definitions deals with the subject and 14.2.17 Runtime Semantics: Evaluation has the following note attached:
An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function. [...]
(the rest of the note concerns calls to super
and methods)
The note is not the definition but serves as a reminder. The rason is scattered through several different places* in the spec but the most relevant is that functions have an particular internal slot that section 9.2 ECMAScript Function Objects defines as:
Internal Slot | Type | Description |
---|---|---|
[[ThisMode]] | (lexical, strict, global) | Defines how this references are interpreted within the formal parameters and code body of the function. lexical means that this refers to the this value of a lexically enclosing function. strict means that the this value is used exactly as provided by an invocation of the function. global means that a this value of undefined is interpreted as a reference to the global object. |
* the "several different places" are just about arrow functions having the [[ThisMode]]
internal slot set to lexical
.
This is the reason arrow functions use this
from the lexical binding at their definition place rather than closures having an effect.
It might also be worth noting that "closure" is ultimately not a very useful term in many cases - every function definition forms a closure. A lot of the times there the mechanism leads to nothing special, so it's not really worth discussing it. It's only interesting (and worth mentioning) when a function uses variables defined outside of it. The ones it "closes over":
const a = 42; //<--+----+
// | |
function f() {// | |
return a; // --+ |
}// |
// |
function g() { } // ----+
Both f
and g
will have access to the variable a
because they are defined in the same environment - the mechanism for their creation does not change based on their body. This can be easily verified (you need to open the browser developer tools for the breakpoint to trigger):
const a = 42;
function f() {
return a;
}
function g() { debugger; }
g();
With that said, g
is simply not worth discussing in the vast majority of cases, as the closure mechanism doesn't have an impact.
Upvotes: 3