OOJavaScript回调:我做得对吗?
背景:我正在构建一个利用JQuery和Facebook Javascript API的Web应用程序。由于一些用户不喜欢Facebook,我还构建了一个thunking层,为不喜欢使用Facebook的用户模拟必要的身份API。为了保持整洁并避免代码重复,我将Javascript代码组织成了几个类 Facebook和jQueryAPI都广泛使用回调。由于我的所有函数都绑定到对象中,我发现我经常使用以下模式:OOJavaScript回调:我做得对吗?,javascript,jquery,callback,Javascript,Jquery,Callback,背景:我正在构建一个利用JQuery和Facebook Javascript API的Web应用程序。由于一些用户不喜欢Facebook,我还构建了一个thunking层,为不喜欢使用Facebook的用户模拟必要的身份API。为了保持整洁并避免代码重复,我将Javascript代码组织成了几个类 Facebook和jQueryAPI都广泛使用回调。由于我的所有函数都绑定到对象中,我发现我经常使用以下模式: var obj_ref = this; some_jquery_function_tha
var obj_ref = this;
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
为了便于阅读,在obj_ref
中的obj
实际上是类的名称
是否有一些漂亮的Javascript魔术更简单或更清晰,或者这是最好的
更新:到目前为止,答案中有一些不错的评论。我应该补充一点,我的回调方法通常需要引用绑定到类的变量或函数。如果我不需要,那么匿名函数包装器是不必要的
更新2:我选择了一个最好的答案,但是你应该仔细阅读所有的答案。每种方法都为可能的解决方案提供了一些有用的见解。我通常只在需要传入额外参数时将回调包装在函数中:
var x = 42;
jQuery_something({}, function(y, z) { obj_ref.callback(x, y, z) });
这是因为您自己无法控制传入回调的参数。但这只是当您需要对范围中的某个var进行引用时。在某些情况下,这意味着您必须创建一个闭包来捕获var,例如在循环中
但如果不是这样的话,我就直接传入对函数的引用:
jQuery_something({}, obj_ref.callback);
即使是这个
也应该可以正常工作,因为回调引用在这个特定示例的范围内(因此无需首先将其复制到obj_ref
:
jQuery_something({}, this.callback);
显然,最后一个示例非常简单明了:“jQuery方法的回调参数是这个对象名为“callback”的方法”我通常只在需要传入额外参数时将回调包装在函数中:
var x = 42;
jQuery_something({}, function(y, z) { obj_ref.callback(x, y, z) });
这是因为您自己不控制传递到回调中的参数。但这只是在您需要对作用域中的某个变量进行引用的情况下。在某些情况下,这意味着您必须创建一个闭包来捕获该变量,例如在循环中
但如果不是这样的话,我就直接传入对函数的引用:
jQuery_something({}, obj_ref.callback);
即使是这个
也应该可以正常工作,因为回调引用在这个特定示例的范围内(因此无需首先将其复制到obj_ref
:
jQuery_something({}, this.callback);
显然,最后一个示例非常简单明了:“jQuery方法的回调参数是这个对象名为‘callback’的方法”是的,这是非常正确的。您可以使用一个实现模式的帮助函数来保存一些代码。是的,这是非常正确的。您可以使用一个实现模式的帮助函数来保存一些代码。如果您需要您的
这作为您的对象参考
,您可以假设对dat进行更新e JavaScript(遗憾的是,您可能不能),您可以使用它来消除包装器:
创建一个新函数,当调用该函数时,该函数本身在所提供的this值的上下文中调用该函数,在调用新函数时,在所提供的任何函数之前有一个给定的参数序列
然后可以将方法绑定到对象,如下所示:
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
将与以下内容相同:
// In some initialization pass...
obj_ref.my_callback_method = obj_ref.my_callback_method.bind(obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
然后,当调用my\u callback\u方法
时,此
将成为obj\u ref
或者,您可以拉入underline.js并使用其or。如果您不想要全部内容,您可以始终从underline.js中获取bind
或bindAll
或者,由于您已经有了jQuery,您可以使用它来代替标准的bind
:
接受一个函数并返回一个始终具有特定上下文的新函数
所以你可以这样做:
// In some initialization pass...
obj_ref.my_callback_method = $.proxy(obj_ref.my_callback_method.bind, obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
感谢您提醒我jQuery版本的bind
,如果您需要将这个作为您的obj_ref
,并且您可以假设更新到最新的JavaScript(遗憾的是,您可能无法),您可以使用它来取消包装器:
创建一个新函数,当调用该函数时,该函数本身在所提供的this值的上下文中调用该函数,在调用新函数时,在所提供的任何函数之前有一个给定的参数序列
然后可以将方法绑定到对象,如下所示:
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
将与以下内容相同:
// In some initialization pass...
obj_ref.my_callback_method = obj_ref.my_callback_method.bind(obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
然后,当调用my\u callback\u方法
时,此
将成为obj\u ref
或者,您可以拉入underline.js并使用其or。如果您不想要全部内容,您可以始终从underline.js中获取bind
或bindAll
或者,由于您已经有了jQuery,您可以使用它来代替标准的bind
:
接受一个函数并返回一个始终具有特定上下文的新函数
所以你可以这样做:
// In some initialization pass...
obj_ref.my_callback_method = $.proxy(obj_ref.my_callback_method.bind, obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
感谢您提醒我jQuery版本的bind
最好使用对象绑定来保留调用上下文:
var objRef = this;
// #1. In this case you will have wrong context inside myCallbackMethod
// often it's not what you want. e.g. you won't be able to call another objRef methods
someJqueryFunction(a, b, objRef.myCallbackMethod);
// #2. Proper way - using proxy (bind) function
someJqueryFunction(a, b, $.proxy(objRef.myCallbackMethod, objRef));
最好使用对象的绑定来保留调用上下文:
var objRef = this;
// #1. In this case you will have wrong context inside myCallbackMethod
// often it's not what you want. e.g. you won't be able to call another objRef methods
someJqueryFunction(a, b, objRef.myCallbackMethod);
// #2. Proper way - using proxy (bind) function
someJqueryFunction(a, b, $.proxy(objRef.myCallbackMethod, objRef));
我对回调也有同样的问题。以下是我如何处理的
- 正如dfsq所说,$.proxy为您完成了这项工作。您不需要任何额外的库,如下划线
- 下划线js有自己的绑定函数,类似于$.proxy
- Apply和call(可以在函数上调用的javascript方法)工作得很好
假设我有一个对象:
var Dog = {
name : "Wolfy",
bark : function(){
console.debug(this.name," barks!");
}
}
var AnotherDog = {
name : "Fang"
}
Dog.bark.call(AnotherDog); //--> Fang barks!
Dog.bark(); //--> Wolfy barks!
在编写“类”时,可以使用此模式处理回调调用
如果您不确定代理或绑定做什么,他们会做一些事情