在forEach()中使用`this`

时间:2015-10-22 19:32:26

标签: javascript foreach

(免责声明:我正在学习JavaScript的过程中) 我有一个像这样的对象构造函数:

var Palette = function() {
    this.colors = ["red", "green", "blue"];
    this.getColorCombinations = function() {
        var combos = [];
        this.colors.forEach(function(a) {
            this.colors.forEach(function(b) {
                if(a !== b) {
                    combos.push([a, b]);
                }
            });
        });
        return combos;
    };
}

var p = new Palette();
alert(JSON.stringify(p.getColorCombinations()));

预期输出:

[["red","green"],["red","blue"],["green","red"],["green","blue"],["blue","red"],["blue","green"]]

经过一些研究后,我意识到这不起作用,因为在内部匿名函数中,"这个"指向全局对象而不是Palette实例。

我的问题是,什么是" JavaScript方式"处理这个问题?我看到类似的问题通过应用,绑定,调用或简单地将this分配给变量来解决,但到目前为止我还没有找到任何哪种方式的示例始终是最佳的练习在内部匿名函数中引用this

here是JsFiddle。 (我将其修改为输出到div以便于文本复制)

1 个答案:

答案 0 :(得分:5)

this作为第二个参数传递给forEach

arr.forEach(callback, thisArg);

MDN Documentation

  

thisArg
  可选的。执行回调时要使用的值。

updated your fiddle显示它的用法,但要点是改变这个电话:

this.colors.forEach(function(a) {
    this.colors.forEach(function(b) {
        if(a !== b) {
            combos.push([a, b]);
        }
    });
});

对此:

this.colors.forEach(function(a) {
    this.colors.forEach(function(b) {
        if(a !== b) {
            combos.push([a, b]);
        }
    });
}, this); // <- pass this as second arg

同样值得注意的是,接受回调的许多其他Array.prototype方法也支持这种习惯用法,包括:

  • forEach
  • map
  • every
  • some
  • filter

但是,如果你只需要指定调用函数时绑定的this,并且该函数而不是设置为对象的属性,则可能是最惯用的方式是Function.prototype.call()Function.prototype.apply()

如果您可以使用ES6,那么箭头函数会更好,因为它从调用上下文继承this

this.colors.forEach(a => {
    this.colors.forEach(b => {
        if(a !== b) {
            combos.push([a, b]);
        }
    });
});