Reputation: 2909
In ES5, if I have to refer to the this
context of parent function in child function I have to store it in a variable and access it inside child function using that variable.
Something like this ...
// variant 1
var self = this;
this.nums.forEach(function (v) {
if (v % 5 === 0)
self.fives.push(v);
});
ECMAScript has arrow functions so I can avoid this:
// variant 2
this.nums.forEach((v) => {
if (v % 5 === 0)
this.fives.push(v)
})
The question that I have is: If I was to declare a variable temp
inside my forEach
function above will this pollute my global scope? If so will this have performance issues and variable conflicts?
Something similar happens in for loop ....
//variant 3
for(var i =0 ;i.......){
var temp = "tempvariable";
//some code here
}
console.log(temp);
//output : tempvariable
What is the difference between variant2 and variant3 code snippets?
Upvotes: 4
Views: 4377
Reputation: 318302
Regular functions use execution context to set the value of this
, meaning that in in most cases, the value of this
is determined by how a function is called, i.e. the value of this
is set according to the environment in which the function is executed.
Arrow functions do not have their own this
value, instead they use lexical scoping, meaning the value of this
inside an arrow function is always inherited from the enclosing scope, i.e. it is set to the this
value of the enclosing execution context.
This is explained in the documentation as well
Until arrow functions, every new function defined its own
this
value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.
....
Arrow functions capture the this value of the enclosing context
The third example posted is just a regular for
loop, and has very little in common with functions, and can't really be compared to the two first code examples.
for
loops work the same in ES2015 as they always have, there generally is no special scope in for
loops for variables, as variables (defined with var
) are function scoped.
However, ES2015 does introduce variables that can are block scoped as wel, and as a for
loop is in fact a block (for (what) {block}
), those variables can be used, and they are defined with either the let
keyword, or the const
keyword for a constant (that can not be changed) .
For those that prefer code
var o = {
nums : [1,2,3,4],
fn : function() {
var self = this;
this.nums.forEach(function(v) {
// "this" in this context would be the window,
// but "self" would be the object "o", hence the common use of this hack
});
this.nums.forEach((v) => {
// "this" in this context, would be the object "o"
// that happens because the "this-value" in the fn() function,
// ... is the parent object
// and the arrow function inherits that this-value
});
for (var i=0; i<this.nums.length; i++) {
// "this" in this context is what it has always been,
// a for-loop has the same this-value as the surrounding scope
}
}
}
o.fn(); // called from global context "window"
Upvotes: 6