在nodejs中,可以利用bind,实现对函数的部分参数预设值,得到一个新函数供以后使用。
这个bind实际上是ecmascript5中新增的功能,这里举例说明。
首先定义一个普通的函数:
function add(a,b) { return a+b; }
通常的调用方式:
add(1,3); // -> 4
add(1,5); // -6
利用bind可以给add预设一些值,如下:
var x = add.bind(null, 3);
x(2); // -> 5
x(100) // -> 103
在某些情况下会比较有用。
其中bind的函数签名与call相很似,第一个参数(null)是准备调用该函数的对象,与参数无关,对于我们这个例子来说,就是null。后面的3,对应的是参数a。
举个不为null的例子:
var obj = {
method: function(name){console.log(name);
}
};
var x1 = obj.method.bind(obj);
x1(“John”); // -> Johnvar x2 = obj.method.bind(obj, “Jack”);
x2(); // -> Jack
再来一个异步的例子:
var inc = function(n, cb) {
setTimeout(function() { cb(null, n+1); }, 1000);
}
var x = inc.bind(null, 4);
x(function(err,result) {
console.log(result);
});
我为什么对这个特性很感兴趣呢?因为它可以简化我们的代码。
先看这个例子(使用了async):
var async = require('async');
var inc = function add(n, cb) {
setTimeout(function() { cb(null, n+1); }, 200);
};
async.series([
function(cb) { inc(3,cb); }, function(cb) { inc(8,cb); }
], function (err,result) {
console.log(result);
});
其中async.series的第一个参数,都要用一些function包在外面,感觉有点繁琐。如果利用bind,可写成:
async.series([
inc.bind(null,3), inc.bind(null,8)
], function(err, result) {
console.log(result);
});
简化了不少吧:)
稍有遗憾的是,由于javascript的语言特性,如果函数中有多个参数,bind只能按顺序预设,不能跳过前面预设后面。比如:
add(a,b)
只能绑定a,或者(a,b),但不能只绑定b。
https://gist.github.com/3745456
这是一个更加准确的关于js中bind的示例。