- I did a lot research online, read many posts including MDN and so on.
- I understand that for traditional defined functions, "this" within functions is defined by objects calling/invoking them (and several different cases, object literal, new constructor, event handler, etc.).
- I understand that for arrow functions, "this" is defined lexically, by the
enclosing context/scope
, not by objects invoking them (though we can use a traditionally defined function (say, A) to wrap arrow functions (say, B) and thus pass the object reference to A first, and then to B)
Here come the questions:
what exactly is an
enclosing context
? This is further convoluted since ES6 allows{}
to be a block/scope/context. Are{}
as delimiters good enough to define an "enclosing context" or it has to be within a function scope.One specific example:
let EventEmitter = require('events').EventEmitter; class Person extends EventEmitter { constructor(name) { super(); this.name = name; } } let mary = new Person('mary'); mary.on('speak', (said) => { console.log(`${this.name}: ${said}`); }); mary.emit('speak', 'you may delay, but time will not');
It simply setups a custom event and adds a callback function when the custom event is triggered. Why the arrow function here doesn't work?
"mary" is the object that calls the "on" function, which should set "this" within "on" to be "mary". The most important thing is, the arrow function is defined in "on" function in its parameter position (lexically enough, right?), why the arrow function can't get "this" value from its "enclosing context", that is, the "on" function here???
the same example, with conventional function definition:
let EventEmitter = require('events').EventEmitter; class Person extends EventEmitter { constructor(name) { super(); this.name = name; } } let mary = new Person('mary'); mary.on('speak', function(s) { console.log(this); }); mary.emit('speak', 'you may delay, but time will not');
Now it works. I understand that given the old way of function definition, console.log(this) can now be dynamically bound to the object calling it. But wait, "mary" is the object and "on" is the immediate function being called. Shouldn't "on" form a closure for the anonymous function within it? And I remember "this" within the nested function cannot access "this" of its closure (the enclosing context, again, huh) and thus should not get the "mary" refernce. Why it works here?
When we talk about something (say, A) within a function, does it mean A have to be in the
{}
of the function, or A could be in the parameter/argument area as well? That is,function(){A}
vs.function(A){}
.similarly, if an arrow function is passed as a parameter like
function(()=>()) {}
, does the outer function considered its enclosing scope? Or the enclosing scope in this case would be the outer of outer function?
The above might sound very stupid. Thanks a lot for your help.