我正在编写一个开源的JavaScript库,我使用 .bind()
方法很重,因为我有一个想法,面向对象的代码看起来更清晰。 (但值得商榷)
例
A1:
var that = this;
setTimeout(function () {
that.method();
}, 0);
VS
B1:
setTimeout(this.method.bind(this), 0);
或者,更实用的代码部分
A2:
remoteDataSource.getData(function (a, b, c, d) {
obj.dataGetter(a, b, c, d);
})
vs B2:
remoteDataSource.getData(obj/* or prototype */.dataGetter.bind(obj));
我使用的是非原生的 bind
对于旧浏览器,一切都很完美,直到我打开一个 绑定的jsperf基准。
它看起来像代码使用 bind
是100倍慢。现在,在重写我的所有库之前,我对那些熟悉javascript引擎的人有一个问题:
是否有可能成为新功能, bind
将得到优化
很快,还是因为JavaScript架构限制而没有机会?
首先,修复jsperf http://jsperf.com/bind-vs-emulate/13。
=您不应在基准测试中重新创建静态函数。这是不现实的,因为在实际代码中,静态函数只创建一次。
你可以看到 var self = this
模式仍然快约60%。但它需要内联函数定义,因为您可以从任何地方进行绑定,因此具有更好的可维护性。
嗯不,内置的绑定语义是荒谬的错综复杂的。
当我绑定时,我只想要这个:
function bind(fn, ctx) {
return function bound() {
return fn.apply(ctx, arguments);
};
}
如果我想预先应用参数或使用一些深层构造黑魔法,我会想要一个完全不同的功能。我不知道为什么任何这个都包含在bind中。
<rant>顺便说一句,同样的问题在于ES5中引入的几乎所有内容,通过强制实现来处理一些与实际中任何人都不相关的理论边缘情况来惩罚常见情况。下一个语言版本继续在同一条路径上。</ rant>
模拟绑定甚至根本不会尝试模拟绑定。即使你试图模仿它,你也无法做到
完全做到这一点,这是不公平的。
所以在其他条件相同的情况下*内置绑定不能比仅仅绑定的常识自定义绑定更快。
*在JIT中,用户代码对内置代码没有明显的缺点。实际上,SM和V8都实现了许多内置函数
在Javascript中。
目前,2013年底,将实施最佳解决方案 手工制造 的版本 Function.prototype.bind
并使用您自己的javascript代码覆盖供应商的“原生”(不是真正的原生)方法,或使用您自己的 myBind
。
Function.prototype.apply
相当快,并且数组切片,连接和移位很慢,所以你最好使用 apply
相反,如果 bind
,或最小化参数操纵 myBind
功能。这将使您没有预填充参数的功能。
所以我认为没有必要将所有内容重写回闭包(丑陋 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。
总结:找到的解决方法并不是那么糟糕。勇敢地使用它们。如果你没有使用功能齐全 bind
,不要离原始概念太远,因为我没有发现它没有在C中实现的原因。这是一个时间问题。