为什么传递 JavaScript 对象的方法不更新对象?

Why does passing a JavaScript object's method not update the object?

我注意到当将对象的方法(更新对象自身的一个属性)作为参数传递给另一个函数时,原始对象不会被修改。

例如:

var obj = {
    foo: 0,
    bar: function () {
        this.foo++;
    }
};

function baz(callback) {
    callback();
}

baz(obj.bar); // does not alter obj
obj.bar(); // increments obj.foo successfully
console.log(obj.foo); // should be 2, not 1

为什么会这样,因为 JavaScript 对象是通过引用传递的?

这是因为函数的上下文 - 或 this 值 - 是基于它的调用方式,而不是它的定义方式。您的 bar 函数不知道它在 obj 对象中。

当您执行 obj.bar(); 时,您是在 obj 的上下文中调用它 ,因此 this 就是您所期望的。

当您执行 baz(obj.bar); 时,您将 bar 函数作为参数传递。它不再与 obj 对象有任何联系。请记住,函数可以像变量一样对待。因此,当 baz 运行其回调时,它是 "global" 上下文中的 运行(thiswindow)。

这里的解决方案是使用 .bind() 到 "lock in" 的 this 值。

baz(obj.bar.bind(obj));

因为你需要将回调绑定到特定对象。

baz(obj.bar.bind(obj));

当您在同一表达式中执行调用时,函数只会自动绑定到 . 之前的对象。简单地访问 属性 不会绑定它。