在第三方JavaScript(FB)中使用匿名函数时解耦
Decoupling when using anonymous functions in third party javascript (FB)
我正在使用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"的访问权限,显然我不想开始编码对控制器具体版本的引用!
我猜我传递函数不正确?
谢谢。
在 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
变量的作用域的闭包)用于使用正确的上下文调用您的函数。有关闭包的更多信息,请点击此处:闭包并不复杂 有关this
的更多信息: 你必须记住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
。我们的所有其他功能都是真正私密的。(我还冒昧地确保函数具有名称,因为这有助于您的工具为您提供帮助。
请注意,我们实际上并没有在函数调用中的任何位置引用inst
,因为它们都是闭包范围的本地。我们甚至可以通过在外部闭包中包含其他var
来拥有私有数据。
- 解耦按钮(两个按钮同时切换),并根据数据显示相应的按钮
- 在 Javascript 中实现解耦代码/回调的正确方法是什么?
- 解耦的键盘映射
- 将https与在同一主机上运行的解耦的前端和后端MEAN应用程序结合使用
- Javascript模块/与DOM元素解耦
- PubSub模式用于在两个解耦的javascript模块之间传输数据
- 如何进一步解耦此JavaScript代码
- 使用javascript函数解包打包的脚本
- 用Html/Javascript填充Textarea,同时保持它与knockout.js解耦
- 解耦一个数据源
- 寻求关于如何从视图中解耦JS代码的建议
- 重构的javascript.解耦标记或分离模块
- 解耦客户机是什么意思?
- 通过rails服务器从chrome扩展解耦Github Oauth2
- 将主干与发布/订阅解耦
- 解耦Angular模块
- 如何服务于解耦的React前端
- 使用mondora/asteroid解耦Meteor客户端和服务器——但是如何解耦呢?
- 我如何解耦java到javascript调用?Applet正在等待自己
- 在第三方JavaScript(FB)中使用匿名函数时解耦