之前的一张海报问Function.bind vs Closure in Javascript : how to choose?
并且部分收到了这个答案,这似乎表明bind应该比闭包更快:
范围遍历意味着,当您要获取存在于不同范围内的值(变量,对象)时,会增加额外开销(代码执行速度变慢) . 使用bind,您将调用具有现有范围的函数,因此不会进行范围遍历 .
两个jsperfs表明bind实际上比closure慢得多 .
这是作为对上述评论发布的
而且,我决定写my own jsperf
那么为什么绑定这么慢(铬含量为70%)?
由于它不是更快并且闭包可以起到相同的作用,应该避免绑定吗?
1 回答
Chrome 59更新:正如我在下面的答案中预测的那样,使用新的优化编译器时,bind不再慢 . 这是包含详细信息的代码:https://codereview.chromium.org/2916063002/
大多数时候没关系 .
除非您正在创建一个
.bind
是瓶颈的应用程序,否则我不会打扰 . 在大多数情况下,可读性比纯粹的性能重要得多 . 我认为使用原生.bind
通常提供更易读和可维护的代码 - 这是一个很大的优点 .但是,重要的是--.bind比较慢
是的,
.bind
比关闭要慢得多 - 至少在Chrome中是这样,至少在v8
中实现的当前方式 . 我个人不得不在某些时候切换Node.JS以解决性能问题(更一般地说,在性能密集的情况下,闭包有点慢) .为什么?因为
.bind
算法比用另一个函数包装函数并使用.call
或.apply
复杂得多 . (有趣的是,它还返回一个函数,其中toString设置为[native function]) .从规范的角度和实现的角度来看,有两种方法可以看待这种情况 . 让我们观察两者 .
首先,让我们看一下规范中定义的绑定算法:
看起来很复杂,不仅仅是一个包装 .
其次,让我们看看它是如何在Chrome中实现的 .
让我们检查v8(chrome JavaScript引擎)源代码中的FunctionBind:
我们可以在实现中看到一堆昂贵的东西 . 即
%_IsConstructCall()
. 这当然需要遵守规范 - 但在许多情况下它也比简单的包装慢 .另一方面,调用
.bind
也略有不同,规格注释"Function objects created using Function.prototype.bind do not have a prototype property or the [[Code]], [[FormalParameters]], and [[Scope]] internal properties"