jjzjj

javascript - $.proxy, bind, call, apply 的区别

coder 2024-07-14 原文

老办法:

var self = this;    
setTimeout(function(){
  console.log(self);
}, 5000);

使用 jQuery:

setTimeout($.proxy(function(){
  console.log(this);
}, this), 5000);

绑定(bind):

setTimeout((function(){
  console.log(this);
}).bind(this), 5000);

随叫随到:

setTimeout((function(){
  console.log(this);
}).call(this), 5000);

似乎 apply 也有效:

setTimeout((function(){
  console.log(this);
}).apply(this), 5000);

http://jsfiddle.net/SYajz/1/

我想知道这些方法之间是否有任何不那么明显的区别

最佳答案

是的,所以我们在这里有三种调用函数的方式。它们都是解决上下文问题的方法,即 this 关键字将根据函数的调用方式具有不同的值。

别名

var self = this;    
setTimeout(function(){
  console.log(self);
}, 5000);

这是一个非常简单的方法。它只是设置一个不会在函数内被覆盖的新变量。该值被关闭,因此当函数在超时后调用时,self 将是您所期望的。

绑定(bind)

setTimeout($.proxy(function(){
  console.log(this);
}, this), 5000);

setTimeout((function(){
  console.log(this);
}).bind(this), 5000);

这两个函数具有相同的结果。这是因为 $.proxy做与 bind 完全相同的事情.但是,bind 是一种新语法,某些较旧的浏览器不支持它。

这是通过将上下文永久“绑定(bind)”到函数来实现的。这意味着,无论函数如何调用,this 的值始终是 bind 的第一个参数的值。

调用/应用

setTimeout((function(){
  console.log(this);
}).call(this), 5000);

setTimeout((function(){
  console.log(this);
}).apply(this), 5000);

同样,这两个函数是相同的。 call之间的唯一区别和 apply是发送给函数的其他参数。 call 需要一个列表(例如 fn.call(context, param1, param2)),而 apply 需要一个数组(fn.apply (上下文,[param1,param2]))。

这两个函数的作用是在指定的特定上下文中调用函数。

但是,这两个函数都不能满足您的要求。他们都在特定的上下文中立即调用该函数,而不是等待 5 秒。这是因为 callapply 的工作方式与 () 相同:代码会立即执行。

结论

哪种方法更合适取决于您的任务。对于简单的操作,别名可能会很好地完成这项工作。但值得记住的是,这引入了另一个变量,并且无法在调用时设置上下文。其他方法在不同情况下也各有优势,尤其是在编写用户提供回调函数的库时。

关于javascript - $.proxy, bind, call, apply 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17014716/

有关javascript - $.proxy, bind, call, apply 的区别的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

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

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

  4. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  5. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  6. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  7. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  8. 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

  9. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  10. ruby - 这两段代码有什么区别? - 2

    打印1:defsum(i)i=i+[2]end$x=[1]sum($x)print$x打印12:defsum(i)i.push(2)end$x=[1]sum($x)print$x后者是修改全局变量$x。为什么它在第二个例子中被修改而不是在第一个例子中?类Array的任何方法(不仅是push)都会发生这种情况吗? 最佳答案 变量范围在这里无关紧要。在第一段代码中,您仅使用赋值运算符=为变量i赋值,而在第二段代码中,您正在修改$x(也称为i)使用破坏性方法push。赋值从不修改任何对象。它只是提供一个名称来引用一个对象。方法要么是破坏性

随机推荐