问题
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);
});
回答1:
Because 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);
回答2:
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);
回答3:
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 common. 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)); }
来源:https://stackoverflow.com/questions/40571633/why-calling-array-prototype-foreach-call-with-an-array-set-to-this-object-not