最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why calling array.prototype.forEach.call() with an array set to THIS object not working - Stack Overflow

programmeradmin5浏览0评论

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 the this of the call to forEach with the thisArg used for the callback. – user663031 Commented Nov 13, 2016 at 7:49
Add a ment  | 

3 Answers 3

Reset to default 5

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 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.

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)); }

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论