我正在使用FB.Event.subscribe()观察者模型来查明用户何时登录。此方法有两个参数,一个包含要监视的内容的字符串,以及回调函数。
我正在关注几个以相同方式处理事件的事件,所以我将回调函数设置为预定义的方法,并将其传递给FB.Event.subscribe(),如下所示:
Controller.prototype.go = function() {
FB.Event.subscribe('auth.login', this.fbHandleStatusChange);
FB.Event.subscribe('auth.logout', this.fbHandleStatusChange);
}
Controller.prototype.fbHandleStatusChange = function(response) {
// Doesn't work
this.otherFunction();
}
Controller.prototype.otherFunction = function() {
alert('hello');
}
不幸的是,这意味着我在fbHandleStatusChange的范围内无法访问'this',显然我不想开始编写对具体版本Controller的引用!
我猜我错误地传递了这个函数?
感谢。
答案 0 :(得分:3)
在JavaScript中,this
完全由如何调用函数定义,而不是定义它的位置。这与其他一些语言不同。 (JavaScript没有方法,它只是有一些函数和一些语法糖,有时候它们看起来像方法。)所以尽管你正确地传递了你的函数,Facebook却不知道你的对象实例,在调用函数时无法正确设置this
。
检查FB.Event.subscribe
文档以查看它是否提供了一种说明用于调用事件处理函数的“上下文”的方法。它可能提供了一种方法。 (这通常是context
或thisArg
参数。)
如果没有,您可以通过闭包轻松解决问题:
Controller.prototype.go = function() {
var self = this;
FB.Event.subscribe('auth.login', handleChange);
FB.Event.subscribe('auth.logout', handleChange);
function handleChange() {
return self.fbHandleStatusChange();
}
}
将this
的副本抓取到名为self
的变量中,该变量由handleChange
函数使用(该变量是包含self
变量的作用域的闭包)使用正确的上下文调用您的函数。有关此处闭包的更多信息:Closures are not complicated有关this
的更多信息,请访问You must remember this
但是,您是否真的会有Controller
的多个实例?从基于类的语言转向JavaScript的人倾向于不必要地使用构造函数(粗略的“类”模拟)。如果你需要有一个以上的对象实例,那么它们是正确的选择,但是如果你在页面上只有一个Controller
对象,那么使用构造函数并摆弄它this
有点矫枉过正。
如果您不需要多个独立的Controller
个实例,那么:
var controllerObject = (function() {
var inst = {};
inst.go = go; // Make `go` a publicly-accessible function of the object
function go() {
FB.Event.subscribe('auth.login', fbHandleStatusChange);
FB.Event.subscribe('auth.logout', fbHandleStatusChange);
}
// This is private to us, so we don't expose it as a property on the object
function fbHandleStatusChange(response) {
// Doesn't work
otherFunction();
}
// This is also private to us
function otherFunction() {
alert('hello');
}
return inst;
})();
通过外部匿名函数创建一个私有作用域,并在该作用域内创建一个实例(inst
)然后返回并引用为controllerObject
。上面的controllerObject
只有一个属性,即函数go
。我们所有的其他功能都是真正私密的。 (我也冒昧地确保函数具有名称,因为helps your tools help you。)
请注意,我们实际上并没有在函数调用中的任何地方引用inst
,因为它们都是闭包范围的本地。我们甚至可以通过在外部闭包中使用其他var
来获取私有数据。