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

笑着哭i 提交于 2019-12-25 18:38:25

问题


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



回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!