草庐IT

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

coder 2024-05-10 原文

我正在编写一个开源 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。 .

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

bind 作为一项新功能是否有可能得到优化 很快,还是因为 JavaScript 架构限制没有机会?

最佳答案

首先,固定jsperf http://jsperf.com/bind-vs-emulate/13 .

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

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


好吧,不,内置的绑定(bind)语义非常复杂。

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

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

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

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

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

因此,在其他条件相同*的情况下,内置绑定(bind)不会比仅绑定(bind)的常识性自定义绑定(bind)更快。

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

关于javascript - Function.prototype.bind() 总是很慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18895305/

有关javascript - Function.prototype.bind() 总是很慢吗?的更多相关文章

  1. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  2. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  3. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  4. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  5. ruby - ruby 中绑定(bind)对象的实际使用 - 2

    昨晚,我在思考我认为是高级ruby​​语言的功能,即Continuations(callcc)和Bindingobjects。我的意思是高级,因为我有静态类型的oo语言背景(C#、Java、C++),我最近才发现ruby​​,所以这些语言特性对我来说不是很熟悉。我想知道这些语言功能在现实世界中的用途是什么。根据我的经验,一切都可以用静态类型的oo语言来完成,但有时我不太同意。我想我在阅读SamRuby的那篇好文章时发现了Continuation的美妙之处/兴趣:http://www.intertwingly.net/blog/2005/04/13/Continuations-for-C

  6. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  7. ruby - Ruby 导入的方法总是私有(private)的吗? - 2

    最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1

  8. ruby-on-rails - 为什么 do/end 和 {} 不总是等价的? - 2

    这个问题在这里已经有了答案:关闭11年前。PossibleDuplicate:RubyblockandunparenthesizedargumentsWhatisthedifferenceorvalueoftheseblockcodingstylesinRuby?我一直认为以下只是同一件事的两种表达方式:[1,2,3].collect{|i|i*2}[1,2,3].collectdo|i|i*2end但是我在我的一个ERB模板中发现了一些奇怪的行为,这两种语法似乎在做两件不同的事情。这段代码效果很好:m))}}%>但是当我将其重写为:m))endend%>...我最终得到了我的@men

  9. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  10. ruby - svn ruby​​ 绑定(bind)是否作为 gem 提供? - 2

    我看到有几十个与svn相关的gem,但是我在其中任何一个上找到的少量文档表明它们是命令行包装器和杂项帮助程序。(svn命令、svn钩子(Hook)等)我在野外看到过执行以下操作的代码:require'svn/core'和SVN.Repos.add(...),但该模块的作者通过apt-get提取了他的svnruby​​工具。这对我来说不是一个选择,因为我正在开发一个windows/osx工具。Thispage列出了一些项目,但特别是,我需要一些可以访问svn+ssh存储库的东西,而且我没有时间花一半的时间来挖掘文档-十几个项目,试图引导每一个。我在寻找哪个gem?从那里开始,我很乐意挖掘

随机推荐