绑定函数而不是闭包来注入额外的参数

2024-01-22

看来不是

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

你可以写

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

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

这有什么缺点吗?不创建闭包是否会带来性能提升?有没有办法保持this关闭会收到什么?


它不是一个“闭包”,它只是一个匿名函数。

我个人更喜欢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,根据参数数量定制,大致相同,这并不奇怪,因为它们本质上做的是相同的工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

绑定函数而不是闭包来注入额外的参数 的相关文章

随机推荐