草庐IT

javascript - 什么时候在 JS 中使用 .bind()

coder 2024-07-29 原文

有大量博客和帖子介绍如何使用 bind() 以及它与 call()apply() 的区别>,但是关于何时为什么 我应该使用 bind()

的例子很少

我发现给出的许多示例都非常罕见,例如:

"use strict";

function Person(firstName, lastName){
  this.firstName = firstName
  this.lastName = lastName
}

Person.prototype.say = function(message){
  return '[' + this + ']: ' + this.firstName + ' ' + this.lastName + ' said: "' + message + '"'
}

Person.prototype.toString = function(){
  return '[Person]'
}

moe = new Person("Mo", "El")


func = moe.say.bind(moe)

console.log(func("asdasda"))

我不知道什么时候我想让一个函数等于某个其他变量并使用该变量而不是原始函数,更不用说那个变量等于 实例的绑定(bind)人物对象。

有什么好的例子吗?

最佳答案

简而言之,.bind()返回一个新函数,该函数在调用时将使用特定的 this 调用原始函数值和(可选)一些预先添加到参数列表中的新参数。

.bind()当您需要传递回调(例如某种函数引用)时使用,但您希望调用者使用特定的 this 调用您的函数值(value)。当您的函数实际上是一个方法并且您想要 this 时,这是最常见的。值设置为特定对象,因此该方法将对该特定对象进行操作。如果你不使用 .bind()在这些情况下,然后是 this value 将由调用者(而不是你)决定,如果调用者没有具体设置它,它将最终成为全局对象或(在严格模式下)undefined .如果您传递的是一种依赖于特定值 this 的方法为了完成它的工作,如果错误 this 将无法正常工作值(value)。

所以,如果你想控制this的值当你的回调被调用时,你可以使用 .bind() .在内部,.bind()只是创建一个小的 stub 函数,它只记住 this您传递它的值并使用 .apply() 调用您的函数设置 this值(value)。 .bind()这并不神奇,因为它也可以手动完成。

.bind()还具有向函数添加额外参数的能力,因此,如果您想添加超出回调的正常调用者使用的参数,您可以使用 .bind() 指定这些参数也。它创建一个 stub 函数,该函数将添加这些额外的参数并设置 this值(value)。


假设您有自己的 Person对象并且您想将一个按钮连接到 .say()特定方法 Person对象。

<button id="talk">Talk</button>

而且,如果您尝试过此 javascript:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say);

您会发现 say()方法被调用,但它会遗漏两件事。它会缺少右边的 this引用(它将被设置为 button 对象,因为这就是 addEventListener 调用其回调的方式)并且它将缺少 say(message) 的参数期待。

因此,您可以使用自己的调用 bob.say() 的 stub 函数自行解决此问题具有所有正确的参数:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", function(e) {
    bob.say("Hello");
});

或者,您可以使用 .bind() :

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say.bind(bob, "Hello"));

.bind() 没有魔法.它可以完全用 javascript 模拟。事实上,这里有一个来自 MDN 的 polyfill:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

由于所有的错误检查,这看起来可能比实际情况更复杂,但它实际上只是返回一个新函数,该函数组合了两组参数,然后使用特定的 this 调用原始函数。值(value)。

关于javascript - 什么时候在 JS 中使用 .bind(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26477245/

有关javascript - 什么时候在 JS 中使用 .bind()的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐