代码之家  ›  专栏  ›  技术社区  ›  Dan YOU

Function.protype.bind()会一直很慢吗?

  •  13
  • Dan YOU  · 技术社区  · 11 年前

    我正在编写一个开源javascript库,我使用 .bind() 方法,因为我认为面向对象的代码看起来更清晰。( 不过还是有争议的 )

    实例

    A1:

    var that = this;
    
    setTimeout(function () {
        that.method();
    }, 0);
    

    B1:

    setTimeout(this.method.bind(this), 0);
    

    或者,更实用的代码部分

    A2:

    remoteDataSource.getData(function (a, b, c, d) {
         obj.dataGetter(a, b, c, d);
    })
    

    对比B2:

    remoteDataSource.getData(obj/* or prototype */.dataGetter.bind(obj));
    

    我使用非本地语言 bind 对于较旧的浏览器,一切都很完美,直到我打开 jsperf benchmark for bind .

    它看起来像是使用 绑定 速度慢了100倍。现在,在重写我的所有库之前,我有一个问题要问那些熟悉javascript引擎的人:

    作为一个新的特征, 绑定 将得到优化 很快,还是因为JavaScript架构的限制而没有机会?

    2 回复  |  直到 11 年前
        1
  •  14
  •   Esailija    11 年前

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

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

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


    不,内置的绑定语义复杂得离谱。

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

    function bind(fn, ctx) {
        return function bound() {
            return fn.apply(ctx, arguments);
        };
    }
    

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

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

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

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

    *在JIT中,用户代码与内置代码相比没有明显的缺点。事实上,SM和V8都实现了许多内置功能 在Javascript中。

        2
  •  0
  •   Dan YOU    11 年前

    目前,2013年底,最好的解决方案将是实施 手工制作的 的版本 Function.prototype.bind 使用自己的javascript代码覆盖供应商的“本机”(不是真正的本机)方法,或者使用自己的 myBind .

    Function.prototype.apply 速度相当快,而数组切片、凹入和移位速度较慢,因此您最好使用 apply 相反,如果 bind ,或最小化中的参数操作 我的绑定 作用这将使您没有参数预填充的功能。

    因此,我认为没有必要将所有内容重写回闭包(丑陋 var that = this; ). 让javascript的功能性获胜。

    更多详细信息和工作代码示例如下:

    http://jsperf.com/function-bind-performance/4

    http://jsperf.com/function-bind-performance/5

    http://jsperf.com/bind-vs-emulate/4 .. 10.

    总结:找到的变通办法并没有那么糟糕。勇敢地使用它们。如果您使用的不是全功能 绑定 ,不要离最初的概念太远,因为我还没有发现它没有在C中实现的原因。这是时间问题。