它不是一个“闭包”,它只是一个匿名函数。
我个人更喜欢bind
版本,因为正如你所说,它更简洁。然而,根据这个 jsperf (http://jsperf.com/anonymous-function-vs-bind http://jsperf.com/anonymous-function-vs-bind),慢了十倍,这让我非常惊讶,特别是因为bind
这里用的好像是原生的。一个假设是bind
,或者更确切地说,它生成的函数,需要查看传入的参数并构造一个参数列表以传递给被调用的函数。
维持this
,你需要一个变体bind
比如下划线的_.partial
,或者你可以自己写一个:
function partial(fn) {
var slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(slice.call(arguments, 1)));
};
}
不幸的是,使用的变化partial
({ onClick: partial(someHandler, 'clicked'); }
)仍然比匿名函数慢十倍。
jsperf 中的另一个测试用例支持参数列表处理导致速度变慢的假设,该测试用例定义了partial1
它只预定义了底层函数的两个参数中的第一个:
function partial1(fn, a) {
return function(b) {
return fn.call(this, a, b);
};
}
使用该方法不需要创建和合并参数列表,只会导致速度降低 25-35%,而不是 90%。
如果我们不在乎路过this
,这使我们能够避免使用Function#call
:
function partial2(fn, a) {
return function(b) {
return fn(a, b);
};
}
那么减速幅度仅为 10%。
然而,如果我们真的想通过this
,那么我们需要将匿名函数版本写为
{ onClick: function(event) { someHandler.call(this, 'clicked', event); } }
这也导致比原始版本慢 20-25%,大概是由于调用的成本Function#call
。所以从这个意义上说,假设你do想要通过this
,匿名函数和我们自制函数的性能partial1
,根据参数数量定制,大致相同,这并不奇怪,因为它们本质上做的是相同的工作。