当前位置: 首页 > 知识库问答 >
问题:

在JS中何时使用. bind()

公西修文
2023-03-14

关于如何使用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"))

我不知道什么时候我想让一个函数等于其他变量,并使用那个变量代替原始函数,更不用说那个变量等于Person对象实例的绑定了。

有什么好的例子吗?

共有3个答案

诸葛雨泽
2023-03-14

这可能是在实际意义上解释它的最简单方法。由于大多数答案都给出了理论定义和解释,我将展示一个简单的用例。当您希望调用的函数具有不同于默认值的this值时,您将使用bind。

var NS = {
  user     : "self",
  getUser  : function() { return this.user; }
};

var CLOSURE = NS.getUser;

// error user is undefined, "this" in that context refers to the global object, "window"
console.log(CLOSURE());

// Bind the function call to NS object
console.log(CLOSURE.bind(NS)());

http://jsfiddle.net/ev3z3td3/2/

戴瑞
2023-03-14

如果您希望函数始终使用特定的此值运行,请使用bind()

当以回调或事件处理程序的形式传递函数时,它对于更多函数式编程非常有用。

var User = function(name) { this.name = name; };
User.prototype.poke = function() { alert "Hey, don't poke " + this.name; };
var bob = User('Bob');

// assume jQuery for brevity, and because it screws with `this` in callbacks
$('#some-element').click(bob.poke.bind(bob));

这将提醒“嘿,不要戳Bob”,因为您向其传递了一个绑定函数。因此,如果该元素是明确关于Bob的,那么将事件处理程序绑定到Bob是有意义的。

但是当然,在没有绑定的情况下,还有其他方法可以做到这一点。

$('#some-element').click(function() {
  bob.poke();
});

这种差异可能是风格问题。而且bind过去并没有在所有浏览器中得到很多支持,所以许多JS程序员找到了其他方法来实现它,许多其他方法至今仍在使用。

一个明显的胜利是,当您希望将相同的函数传递到许多不同的位置,并且希望显式地设置this

var bobPoke = bob.poke.bind(bob);

onFoo(bobPoke);
onBar(bobPoke);
onBaz(bobPoke);
楚建柏
2023-03-14

简而言之,. bind()返回一个新函数,当调用该函数时,该函数将调用具有特定this值的原始函数,并(可选地)在参数列表中添加一些新参数。

。bind()用于需要传递回调(例如某种函数引用),但希望调用方使用特定的值调用函数的情况。当函数实际上是一个方法,并且希望将This值设置为特定对象的值,以便该方法将对该特定对象进行操作时,这种情况最为常见。如果不使用。bind()在这些情况下,值将由调用者(而不是您)确定,如果调用者没有专门设置它,它将成为全局对象或(在严格模式下)未定义的。如果您传递的方法依赖于this的特定值来完成其工作,那么它将无法使用错误的this值正常工作。

因此,如果要在调用回调时控制this的值,可以使用。bind()。在内部,。bind()只创建一个小存根函数,它只记住传递给它的值,并使用调用函数。apply()设置此值<代码>。bind()并不神奇,因为它也可以手动完成。

。bind()还具有向函数添加额外参数的功能,因此,如果要添加超出回调的正常调用方使用范围的参数,可以使用指定这些参数。bind()也是。它创建一个存根函数,该函数将添加这些额外参数并设置this值。

假设您拥有Person对象,并且希望将一个按钮连接到。say()方法,用于特定的对象。

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

如果您尝试使用此javascript:

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

您会发现调用了say()方法,但它缺少两件事。它将丢失正确的this引用(它将被设置为按钮对象,因为addEventListener就是这样调用它的回调的),并且它将丢失say(消息)期望的参数。

因此,您可以使用自己的存根函数来解决这个问题,该函数调用具有所有正确参数的bob.say()

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

或者,您可以使用。绑定()

"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值调用原始函数。

 类似资料:
  • 我在React中使用了不可变的js和react-im身不由己的角色类型。 当页面初始化时,没有问题,一切正常,没有警告。控制台日志显示是。当我添加一条新评论时,它看起来效果不错,但有一个警告 警告:失败的propType:提供给的prop

  • 问题内容: 如何在React中使用jQuery UI?我已经通过Googling看到了几个示例,但它们似乎都已过时。 问题答案: 如果您 确实 需要这样做,这是我正在使用的一种方法。 计划: 创建一个组件来管理jQuery插件 。该组件将提供以React为中心的jQuery组件视图。此外,它将: 使用React生命周期方法来初始化和拆除jQuery插件; 使用React 作为插件配置选项并连接到插

  • 问题内容: 输入完成后,我会正确获得信用卡信息,我调用了一个函数来验证使用luhn模块的信用卡(npm install luhn),因为我使用的是: 未捕获的ReferenceError:未定义require 很抱歉,如果这是一个简单的问题,但由于找不到npm打包用法的逻辑短解决方案。我称这个时间功能。 再次相同的错误。 因此在js中,必须有使用npm模块的简单方法。但是我找不到。请我需要帮助。

  • 问题内容: 我是pthread的新手,我正试图了解它。我看到了一些类似以下的示例。 我可以看到API阻止了它,并且我看到了一些示例,其中主要功能都被API阻止了。我不明白什么时候使用什么? 我指的是以下站点-https://computing.llnl.gov/tutorials/pthreads/。我无法获得何时使用和何时使用的概念。 有人可以解释一下吗?此外,将感谢一个很好的pthread教程

  • 有什么方法可以在持续时间对象上使用moment.js方法吗?我在文档中的任何地方都找不到它,它也不是持续时间对象的属性。 我希望能够做到以下几点: 此外,如果有任何其他库可以轻松容纳这种功能,我会对推荐感兴趣。 谢谢

  • 我有个疑问 当我使用猫鼬时,我得到了上述警告。如何清除它们?