绑定函数而不是闭包来注入额外的参数 [英] Bound function instead of closure to inject extra arguments

查看:66
本文介绍了绑定函数而不是闭包来注入额外的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎而不是

{  onClick: function(event){  someHandler('clicked', event); }  }

你可以写

{  onClick: someHandler.bind(null, 'clicked'); }

看起来更简洁,感觉更实用。

which looks more concise and feels more "functional".

这有什么缺点吗?没有创建闭包是否有性能提升?有没有办法保持闭包收到的这个

Are there any drawbacks to this? Is there a performance gain by not having created a closure? Is there a way to keep the this that the closure would have received?

推荐答案

这不是封闭,它只是一个匿名函数。

It's not a "closure", it's just an anonymous function.

我个人更喜欢 bind 版本,因为正如你所说,它更简洁。但是,根据这个jsperf( http://jsperf.com/anonymous-function-vs-bind ),它慢了十倍,这让我大吃一惊,特别是因为这里使用的 bind 似乎是原生的。一个假设是 bind ,或者更确切地说,它生成的函数需要解决传入的参数并构造一个参数列表以传递给被调用的函数。 。

Personally I prefer the bind version because as you say, it's more concise. However, according to this jsperf (http://jsperf.com/anonymous-function-vs-bind), it's ten times slower, which surprises me greatly, especially since the bind used here seems to be the native one. One hypothesis is that bind, or rather the function it generates, needs to do work around looking at the arguments passed in and constructing an argument list to pass along to the function being called.

要维护,您需要 bind 比如Underscore的 _。partial ,或者你可以自己写一个:

To maintain this, you need a variant of bind such as Underscore's _.partial, or you could write one yourself:

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)));
    };
}

不幸的是,使用部分的变化 {onClick:partial(someHandler,'clicked');} )仍然比匿名函数慢十倍。

Unfortunately, the variation using partial ({ onClick: partial(someHandler, 'clicked'); }) is still ten times slower than the anonymous function.

jsperf中的另一个测试用例支持参数列表处理导致速度减慢的假设,jsperf定义了一个 partial1 ,它只预定义了第一个底层函数的两个参数:

The hypothesis that argument list handling is causing the slowdown is supported by another test case in the jsperf, which defines a partial1 which predefines just the first of exactly two arguments to the underlying function:

function partial1(fn, a) {
    return function(b) {
        return fn.call(this, a, b);
    };
}

使用那个不必创建和合并参数列表的那个,导致放缓仅为25-35%,而不是90%。

Using that one, which doesn't have to create and merge argument lists, results in a slowdown of only 25-35%, instead of 90%.

如果我们不关心通过这个,它允许我们避免使用函数#call

If we don't care about passing through this, which allows us to avoid using Function#call:

function partial2(fn, a) {
    return function(b) {
        return fn(a, b);
    };
}

然后减速仅为10%。

但是,如果我们真的想要通过这个,那么我们需要将匿名函数版本写为

However, if we really want to pass through this, then we need to write the anonymous function version as

{ onClick: function(event) { someHandler.call(this, 'clicked', event); }  }

这也导致原始版本减速20-25%,可能是由于调用函数#call 的成本。所以从这个意义上来说,asusming你想要通过这个,匿名函数的性能和我们自己的 partial1 ,根据参数的数量而定制,大致相当,这并不奇怪,因为它们基本上做了相同的工作。

which also results in a 20-25% slowdown from the original version, presumably due to the cost of invoking Function#call. So in that sense, asusming you do want to pass through this, the performance of the anonymous function and our home-grown partial1, customized for number of arguments, is roughly equivalent, which is not surprising since they're essentially doing identical work.

这篇关于绑定函数而不是闭包来注入额外的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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