使用Function.prototype.bind和一个参数数组? [英] Using Function.prototype.bind with an array of arguments?

查看:108
本文介绍了使用Function.prototype.bind和一个参数数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何用一个参数数组调用Function.prototype.bind,而不是硬编码参数? (不使用ECMA6,所以没有传播运算符)。

我试图在一个使用回调的模块周围放置一个promise包,并且我想绑定所有的参数传入我的包装方法并绑定它们。然后我想用我自己的回调调用部分应用的绑定函数,这将解决或拒绝承诺。

  var find = function(){
var deferred,bound;
deferred = Q.defer();
bound = db.find.bind(null,arguments);
bound(function(err,docs){
if(err){
deferred.fail(err);
} else {
deferred.resolve(docs) ;
}
});
return deferred.promise;

$ / code>

但显然这不起作用,因为绑定需要参数而不是数组参数。我知道我可以通过将回调插入参数数组的末尾并使用apply来完成此操作:

  arguments [arguments.length ] = function(err,docs){...} 
db.find.apply(null,arguments);

或者迭代参数数组并为每个参数重新赋值:

  var bound,context; 
for(var i = 0; i< arguments.length; i ++){
context = bound?绑定:db.find;
bound = context.bind(null,arguments [i]);

bound(function(err,docs){...})



<但是这两种方法都很脏。任何想法?

解决方案

.bind 是一个正常的功能,所以你可以在它上面调用 .apply

你所要做的就是将原始函数作为第一个参数传递,并且将所需的这个变量作为参数数组中的第一项:

  bound = db.find.bind .apply(db.find,[null] .concat(arguments)); 
// ^ ----- ^ ^ ----- ^此

是否可以认为这是清洁与否是留给读者的。


How can I call Function.prototype.bind with an array of arguments, as opposed to hardcoded arguments? (Not using ECMA6, so no spread operator).

I'm trying to put a promises wrapper around a module that uses callbacks and I want to bind all of the arguments passed in to my wrapper method and bind them. Then I want to call the partially applied bound function with my own callback, which will resolve or reject a promise.

var find = function() {
  var deferred, bound;
  deferred = Q.defer();
  bound = db.find.bind(null, arguments);
  bound(function(err, docs) {
    if(err) {
      deferred.fail(err);
    } else {
      deferred.resolve(docs);
    }
  });
  return deferred.promise;
}

But obviously this doesn't work because bind expects arguments rather than an array of arguments. I know I could do this by inserting my callback onto the end of the arguments array and using apply:

arguments[arguments.length] = function(err, docs) { ... }
db.find.apply(null, arguments);

Or by iterating over the arguments array and rebinding the function for each argument:

var bound, context;
for(var i = 0; i < arguments.length; i++) {
   context = bound ? bound : db.find;
   bound = context.bind(null, arguments[i]);
}
bound(function(err, docs) { ... })

But both of these methods feel dirty. Any ideas?

解决方案

.bind is a normal function, so you can call .apply on it.
All you have to do is pass the original function as the first param and the desired THIS variable as the first item in the array of arguments:

bound = db.find.bind.apply(db.find, [null].concat(arguments));
//      ^-----^            ^-----^   THIS

Whether that can be considered cleaner or not is left to the reader.

这篇关于使用Function.prototype.bind和一个参数数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆