【发布时间】:2019-08-01 21:00:56
【问题描述】:
一些更新: 感谢大家的帮助。我想这可能是关键的混淆点:参数区域中的“this”不被视为函数“内部”,因此不会遵循 mdn 指定的规则(this 指向调用该方法的 obj)。下面的例子:
someObj {
someF(//but if "this" shows up here, it doesn't point to someObj) {
//when called, "this" here will point to someObj
}
}
原始问题:
看了很多文档后,我以为我对此有很好的理解,但我错了。
下面的例子来自MDN:
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
// Here "this" points to obj
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
// ^---- Note, why it points to obj, not array [2,5,9]???
// Here "this" points to obj
};
const obj = new Counter();
obj.add([2, 5, 9]);
obj.count;
// 3
obj.sum;
// 16
我明白了:
- 需要将
this传递给forEach,否则在回调函数中,this会指向全局/窗口(非严格模式)。 - 在
function(array)的大部分区域内,this指向 obj(从新的Counter()创建),如 cmets 所示。 - 回调函数如何使用从 forEach 传递的“this”作为第二个参数。我对此没有任何疑问
但基于此article on MDN 具体来说:
"作为对象方法,当函数作为对象的方法被调用时 对象,它的 this 设置为调用该方法的对象。”
不应该将this(由 ^---Note 突出显示)传递到指向数组对象的回调点中,即在这种情况下为 [2,5,9]。为什么会指向 obj 而不是数组?
非常感谢您的帮助,这太令人困惑了。
【问题讨论】:
-
forEach不是对象的一部分。它在array上调用,它与add内部的this指向Counter 实例不同。因此,要访问 Counter 实例变量,您需要传递this,它将替换通常的arraythis。如果你不在this里面forEach指向array。 -
谢谢,@GillesC。引用自 mdn “相同的概念适用于定义在对象原型链上某处的方法。如果该方法位于对象的原型链上,则 this 指的是调用该方法的对象,就好像该方法位于该对象上一样。”所以 forEach 在数组的原型链上,应该指向数组。是的,我们需要传递this,但是传入的“this”在array.forEach函数调用中,其中“this”应该已经表示[2,5,9],而不是obj
-
感谢@HereticMonkey。我对如何在 forEach 的回调函数中使用第二个 this 毫无疑问。我的问题是,这里的方法(forEach)是在对象(array[2,5,9])上调用的,为什么其参数区的“this”指向obj,而不是array[2,5,9]
-
@GillesC 顺便说一句,如果我不将“this”作为 forEach 作为第二个参数传递,回调中的“this”将指向非严格模式下的窗口,而不是数组
标签: javascript foreach this