将函数作为回调传递时的原型问题

时间:2014-09-15 14:45:14

标签: javascript angularjs

我有一个在后台运行并同步数据的服务。我将一个控制器注册为回调,当更新发生时,我想关闭一个回调。所有这些都很有效,但是,现在在回调中我想调用服务中的另一个函数....

Controller.prototype.update = function(){
  this.service.test();
};

Plunker

这无法说服务未定义但我无法弄清楚原因。我的理解是原型允许继承(这是我的JS技能中的一个弱点),如果我希望子对象继承某些功能同时允许我覆盖其他一些功能(在这种情况下更新),我将需要它。我想要这个选项,所以我想保留原型上的功能。 所以我想避免像 this 这样的内容,即使它有效

1 个答案:

答案 0 :(得分:2)

问题是JavaScript中的this关键字可能会根据执行上下文而改变。它取决于调用它的位置,而不是它的定义位置。

由于调用方式,您正在丢失上下文。如果您想确保维护上下文,可以使用bind()功能将修复上下文设置为您选择的内容:

// Creates a new function that is permanantly bound
// to the current object that `this` is pointing to
service.register(this.update.bind(this));

这是updated Plunkr showing the working code using the bind() function.

使用闭包的替代选项

如果你不能使用bind()函数,或者上面列出的MDN文章中的Polyfill实现是不可行的,那么你也可以使用一个闭包来确保正确的调用:

//Capture the current `this` using a closure
var _this = this;

service.register(function(){
   _this.update();
});

示例Plunker:http://plnkr.co/edit/buv66fexxZr04x7EACvE?p=preview