Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OOJavaScript回调:我做得对吗?_Javascript_Jquery_Callback - Fatal编程技术网

OOJavaScript回调:我做得对吗?

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

背景:我正在构建一个利用JQuery和Facebook Javascript API的Web应用程序。由于一些用户不喜欢Facebook,我还构建了一个thunking层,为不喜欢使用Facebook的用户模拟必要的身份API。为了保持整洁并避免代码重复,我将Javascript代码组织成了几个类

Facebook和jQueryAPI都广泛使用回调。由于我的所有函数都绑定到对象中,我发现我经常使用以下模式:

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!
在编写“类”时,可以使用此模式处理回调调用

如果您不确定代理或绑定做什么,他们会做一些事情