this context in forEach

倾然丶 夕夏残阳落幕 提交于 2020-06-27 18:37:32

问题


I was reading the Mozilla Documentation, but I don't understand the this which is passed into the function. Could anyone explain more about the usage of the this argument here?

function Counter() {
  this.sum = 0;
  this.count = 0;
}

Counter.prototype.add = function(array) {
  array.forEach(function(entry) {
    this.sum += entry;
    ++this.count;
  }, this); //Why is this passed here?
};

var obj = new Counter();
obj.add([2, 5, 9]);
obj.count
// 3 
obj.sum
// 16

回答1:


Per the Mozilla documentation:

thisArg Optional

Value to use as this when executing callback.

And also:

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. (Emphasis added)

What passing the thisArg to forEach does is bind the context. By default, this in forEach is the global window object, because undefined is used for this. Passing the context permits you to access things from that context.

In the prototype, this is the Counter constructor, and passing then allows you to set the context of which this is inside the forEach. So, instead of this being window inside the forEach, it is now Counter, and you can access variables such as this.sum otherwise not available due to the context.




回答2:


Since functions are self contained, your doing:

function x(){
  this.test = 5
}

it only exists within the scope of the function.

If you start nesting functions as you have, if you want the scope to remain the same, you need to inform the function just that.

It is along the same lines of using the bind function.

function test(){
  this.a = 4;
  var y = function(){
    this.a += 1;
  }.bind(this);
}

if you didnt bind, for example, this.a would would be undefined, so the line: this.a += 1; would be the same as saying: this.a = undefined + 1

but when you bind, it will say: this.a = 4 + 1




回答3:


You can prevent the scoping by using arrow function in es6.

An arrow function expression has a shorter syntax compared to function expressions and does not bind its own this, arguments, super, or new.target.

function Counter() {
  this.sum = 0;
  this.count = 0;
}

Counter.prototype.add = function(array) {
  array.forEach(entry=>{this.sum += entry;++this.count});
};

var obj = new Counter();
obj.add([2, 5, 9]);
console.log(obj);

This comes handy when the alternative methods available in es5 are using bind() to bind the this parameter, or using the thisArg that comes with forEach as already explained in the other answers.



来源:https://stackoverflow.com/questions/39813975/this-context-in-foreach

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