Function.prototype.bind()总是很慢吗?

Dan*_*Dan 13 javascript performance v8 spidermonkey late-binding

我正在编写一个开源的javascript库,我使用的.bind()方法很多,因为我知道面向对象的代码看起来更清晰.(虽然有争议)

A1:

var that = this;

setTimeout(function () {
    that.method();
}, 0);
Run Code Online (Sandbox Code Playgroud)

VS

B1:

setTimeout(this.method.bind(this), 0);
Run Code Online (Sandbox Code Playgroud)

或者,更实用的代码部分

A2:

remoteDataSource.getData(function (a, b, c, d) {
     obj.dataGetter(a, b, c, d);
})
Run Code Online (Sandbox Code Playgroud)

vs B2:

remoteDataSource.getData(obj/* or prototype */.dataGetter.bind(obj));
Run Code Online (Sandbox Code Playgroud)

我使用非原生bind的浏览器,一切都很完美,直到我为bind打开jsperf基准.

看起来代码使用bind速度要快100倍.现在,在重写我的所有库之前,我对那些熟悉javascript引擎的人有一个问题:

作为新功能,是否有可能bind很快得到优化,或者由于JavaScript体系结构限制而没有机会?

Esa*_*ija 14

首先,修复了jsperf http://jsperf.com/bind-vs-emulate/13.

=您不应在基准测试中重新创建静态函数.这是不现实的,因为在实际代码中,静态函数只创建一次.

您可以看到该var self = this模式仍然快约60%.但它需要内联函数定义,因为您可以从任何地方进行绑定,因此具有更好的可维护性.


嗯不,内置的绑定语义是荒谬的错综复杂的.

当我绑定时,我只想要这个:

function bind(fn, ctx) {
    return function bound() {
        return fn.apply(ctx, arguments);
    };
}
Run Code Online (Sandbox Code Playgroud)

如果我想预先应用参数或使用一些深层构造黑魔法,我会想要一个完全不同的功能.我不知道为什么任何这个都包含在bind中.

<rant>顺便说一句,同样的问题在于ES5中引入的几乎所有内容,通过强制实现来处理一些与实际中任何人都不相关的理论边缘情况来惩罚常见情况.下一个语言版本继续在同一条路径上.</ rant>

模拟绑定甚至根本不会尝试模拟绑定.即使你试图模仿它,你也无法完全做到这一点,这是不公平的.

因此,在其他条件相同的情况下*内置绑定不能比仅仅绑定的常识自定义绑定更快.

*在JIT中,用户代码对内置代码没有明显的缺点.事实上,SM和V8都在Javascript中实现了许多内置函数.