Here I have a number array. I tried to test if Array.prototype.forEach
can be used on array in a different way than the traditional way. In traditional way we pass the THIS argument as second parameter to forEach
.
Here I used Array.prototype.forEach.call()
and for this I used the array as argument to call method.
But this indication the window object.
Why is that ?
number=[1,2,3,4,5];
Array.prototype.forEach.call(number,function(elem){
console.log(this);
});
Here I have a number array. I tried to test if Array.prototype.forEach
can be used on array in a different way than the traditional way. In traditional way we pass the THIS argument as second parameter to forEach
.
Here I used Array.prototype.forEach.call()
and for this I used the array as argument to call method.
But this indication the window object.
Why is that ?
number=[1,2,3,4,5];
Array.prototype.forEach.call(number,function(elem){
console.log(this);
});
Share
Improve this question
edited Nov 13, 2016 at 7:45
George Kagan
6,1348 gold badges49 silver badges50 bronze badges
asked Nov 13, 2016 at 7:40
AL-zamiAL-zami
9,08617 gold badges77 silver badges136 bronze badges
1
-
1
What do you expect
this
to be inside the callback? You're confusing thethis
of the call toforEach
with thethisArg
used for the callback. – user663031 Commented Nov 13, 2016 at 7:49
3 Answers
Reset to default 5Because assuming forEach
has not been overwritten, and this array still has the normal prototype, this:
Array.prototype.forEach.call(number,function(elem){ });
Is no different from:
number.forEach(function(elem){ });
In a forEach
callback function, unless you pass the thisArg
, the function is called like a normal callback.
From MDN:
If a
thisArg
parameter is provided toforEach()
, it will be passed tocallback
when invoked, for use as itsthis
value. Otherwise, the valueundefined
will be passed for use as itsthis
value. Thethis
value ultimately observable bycallback
is determined according to the usual rules for determining the this seen by a function.
To set the thisArg
while using .call
, you would need to pass one more argument:
Array.prototype.forEach.call(number,function(elem){ }, number);
According to MDN
If a thisArg parameter is provided to forEach(), it will be passed to callback when invoked, for use as its this value. Otherwise, the value undefined will be passed for use as its this value. The this value ultimately observable by callback is determined according to the usual rules for determining the this seen by a function.
In the following snippet, we explicitly pass as the thisArg
the number
and we have as result that you are looking for.
number=[1,2,3,4,5];
Array.prototype.forEach.call(number,function(elem){
console.log(this);
},number);
Yes, I know that jQuery's $.each
sets this
inside the callback to the value of the element. But that's not how Array#forEach
works. Instead, this
is usually not set, unless the second thisArg
parameter is specified.
number=[1,2,3,4,5];
Array.prototype.forEach.call(number, function(elem) {
console.log(elem);
^^^^ Access element via parameter, not `this`
});
If for some reason it is important that you pass some this
into the callback, then specify it as another parameter to forEach
, as mentioned in other answers. This this
will be the same on each invocation of the callback; it has nothing to do with the current iteration.
Array.prototype.forEach.call(
number,
function(elem) {
console.log("Inside callback, this is", this); // 42
console.log(elem);
},
42);
Using thisArg
is not that mon. Frequently, it is used if an object method is being passed as the callback:
obj = {
vals: [1, 2, 3],
message: "the value is",
alert(x) { alert(this.message + x); },
alertVals() { this.vals.forEach(this.alert, this); }
};
obj.alertVals();
This is an alternative approach to either of
alertVals() { vals.forEach(this.alert.bind(this)); }
alertVals() { vals.forEach(elt => this.alert(elt)); }