在第三方javascript(FB)中使用匿名函数时的解耦
我使用FB.Event.subscribe()观察者模型来确定用户何时登录。此方法接受两个参数,一个包含要监视的内容的字符串和回调函数 我正在跟踪几个以相同方式处理事件的事件,因此我将回调函数设置为预定义方法,并将其传递给FB.event.subscribe(),如下所示:在第三方javascript(FB)中使用匿名函数时的解耦,javascript,oop,facebook,Javascript,Oop,Facebook,我使用FB.Event.subscribe()观察者模型来确定用户何时登录。此方法接受两个参数,一个包含要监视的内容的字符串和回调函数 我正在跟踪几个以相同方式处理事件的事件,因此我将回调函数设置为预定义方法,并将其传递给FB.event.subscribe(),如下所示: Controller.prototype.go = function() { FB.Event.subscribe('auth.login', this.fbHandleStatusChange); FB.E
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”的访问,显然我不想开始编写对控制器具体版本的引用
我猜我传递的函数不正确
谢谢。在JavaScript中,
这个
完全由函数的调用方式来定义,而不是定义在什么地方。这与其他一些语言不同。(JavaScript没有方法,它只有函数和一些语法糖,使它们有时看起来像方法。)因此,尽管您正确地传递了函数,Facebook不知道您的对象实例,在调用函数时无法正确设置此
检查FB.Event.subscribe
文档,看看它是否提供了一种方式来说明使用什么“上下文”来调用事件处理程序函数。它可能提供了一种实现这一点的方法。(这通常是一个上下文
或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
变量的作用域上的闭包)使用,以正确的上下文调用函数。有关闭包的更多信息,请参见此处:有关此的更多信息:
不过,您是否真的要有多个控制器的实例?从基于类的语言学习JavaScript的人倾向于不必要地使用构造函数(粗略的“类”模拟)。如果您需要一个对象的多个实例,那么它们是正确的选择,但是如果您在页面上只需要一个控制器对象,那么使用构造函数和摆弄这个就太过分了
如果您不需要多个独立的控制器
实例,那么:
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
)<代码>控制器对象
在上述中只有一个属性,即函数go
。我们所有的其他功能都是真正的私人功能。(我还冒昧地确保函数有名称,因为这样做。)
请注意,我们实际上并没有在函数调用中的任何地方引用inst
,因为它们都是闭包范围的局部。我们甚至可以通过在外部闭包中包含其他var
s来拥有私有数据。为了向其他读者澄清,在原型中定义:var self=this。go@Steve:很抱歉,我只是在添加解释时注意到了这一点。:-)很高兴这帮了忙(幸亏找到了遗漏的部分)。回复:新实例。我正在开发其他人的代码,他们使用的是MVC框架,所以我不能这样放肆。这是一个很好的观点,我使用全局变量作为解决方案,然后突然我的OOP意识开始了。匿名包装器可能是一个很好的折衷方案,但由于它的代码基础是什么,我认为它会增加额外的工作来解决一些问题。再次感谢您的深入反馈!我们一定要尽快全面阅读这些文章。@Steve::-)只是介绍其他选择,是否正确取决于具体情况。