如何在forEach循环中使用'this'进行函数调用

70
在下面的对象中,我在使用“this”引用时遇到了问题:
function SampleObject(){
    this.addObject = function(object){...}
    ...
    // more code here
    ...
    this.addNewObjects= function(arr){
        arr.forEach( function (obj) {
            this.addObject(new Obj(obj.prop1, obj.prop2));
        });
    }
}

我假设上下文正在改变,而'this'是指迭代的'obj',而不是'SampleObject'。我已经使用普通的for循环解决了问题,但我很好奇为什么这不起作用,并想知道是否有其他方法可以做到这一点。


你在哪里/如何调用 SampleObject() - Danny
1
我建议阅读关于this的相关内容:这里或者这里 - javinor
@javinor 谢谢,这些文章非常有帮助。函数创建作用域,因此“this”由Window对象拥有,这是“this”的默认所有者。 - user3339411
1
这个问题与“this”的所有者完全不重复。 - Scott Hillson
2个回答

137
你可以将这个存储在变量中:
var self = this;
this.addNewObjects = function(arr){
    arr.forEach(function(obj) {
        self.addObject(new Obj(obj.prop1, obj.prop2));
    });
}

或者使用 bind:

this.addNewObjects = function(arr) {
    arr.forEach(function(obj) {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    }.bind(this));
}

顺便提一下,如果没有这些this,它将是窗口对象而不是 obj。 This 总是使用 new 关键字创建的对象或正常函数中的 window 对象。在严格模式下,this 在这种情况下将为未定义。

更新:使用 ES6,您可以使用箭头函数:

this.addNewObjects = function(arr) {
    arr.forEach((obj) => {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    });
}

箭头函数没有自己的this,它们从外部作用域获取它。

更新2:根据@viery365的评论,您可以将this用作forEach的第二个参数,并将其作为函数的上下文:

this.addNewObjects = function(arr) {
    arr.forEach(function(obj) {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    }, this);
}

您可以在MDN forEach页面上阅读此内容。


4
针对 forEach()(与问题相关),可以在回调函数后使用“内置”的第二个参数—thisArg。例如:arr.forEach(callback, this); 文档 - viery365
@viery365 哦,不知道呢,你应该用我们的解决方案添加自己的答案。这对于只使用 forEach() 可能更好。 - jcubic
这个特定问题可能被标记为重复,因此没有回答选项。但是无论如何,你的答案几乎完美,我也从中学到了东西。我的评论只是一个补充。 - viery365

2
const array1 = [
  {name : "john", age: 20}, {name : "sarah", age: 70}
  ];

array1.forEach(element => this.print(element));

print = (data) =>
{
  console.log(data.name);
}
// expected output: "john"
// expected output: "sarah"

有更好的方法来做这件事

array.forEach(obj => this.functionName(params));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接