关于如何使用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
对象实例的绑定了。
有什么好的例子吗?
这可能是在实际意义上解释它的最简单方法。由于大多数答案都给出了理论定义和解释,我将展示一个简单的用例。当您希望调用的函数具有不同于默认值的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/
如果您希望函数始终使用特定的此值运行,请使用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);
简而言之,. 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方法吗?我在文档中的任何地方都找不到它,它也不是持续时间对象的属性。 我希望能够做到以下几点: 此外,如果有任何其他库可以轻松容纳这种功能,我会对推荐感兴趣。 谢谢
我有个疑问 当我使用猫鼬时,我得到了上述警告。如何清除它们?