提问人:Tom 提问时间:12/30/2016 更新时间:10/31/2023 访问量:10693
为什么需要 JavaScript bind()?
Why is JavaScript bind() necessary?
问:
示例 1 中的问题是“this”指的是全局名称而不是 myName 对象。
我理解使用 bind() 将 this 的值设置为特定对象,因此它解决了示例 1 中的问题,但为什么首先会出现这个问题?它只是 Javascript 的创建方式吗?
我也想知道为什么示例 3 解决了这个问题以及示例 2 和 3 之间的区别。
this.name = "John"
var myName = {
name: "Tom",
getName: function() {
return this.name
}
}
var storeMyName = myName.getName; // example 1
var storeMyName2 = myName.getName.bind(myName); // example 2
var storeMyName3 = myName.getName(); // example 3
console.log("example 1: " + storeMyName()); // doesn't work
console.log("example 2: " + storeMyName2()); // works
console.log("example 3: " + storeMyName3); // works
答:
从 Function.prototype.bind() 上的 mdn wed 文档,
实例的方法创建一个新函数,该函数在调用时调用此函数,其关键字设置为提供的值,并在调用新函数时提供任何参数之前的给定参数序列。
bind()
Function
this
因此,当您第一次执行时,它采用全局 ( )。var storeMyName = myName.getName;
name
this.name = "John"
当您使用 function 时,它开始引用当前闭包(在本例中为 )中定义的名称,因此打印 .bind()
myName
Tom
第三次,由于该函数是立即调用的,因此其作用域位于其自己的本地对象内,因此在闭包中打印值。Tom
为什么需要 JavaScript bind()?
的值由函数的调用方式决定。如果是您调用该函数,则通常无需使用 ,因为您可以控制如何调用该函数,从而控制其值。this
.bind
this
但是,调用函数的通常不是您。函数作为回调和事件处理程序传递给其他函数。它们由其他代码调用,您无法控制函数的调用方式,因此无法控制将引用的内容。this
如果您的函数需要设置为特定值,而您不是调用该函数的人,则需要将该函数设置为特定值。this
.bind
this
换句话说:允许您在不立即调用函数的情况下设置 的值。.bind
this
以下是引用/调用函数的比较:
+-------------------+-------------------+
| | |
| time of | time of |
|function execution | this binding |
| | |
+-------------------+-------------------+-------------------+
| | | |
| function object | future | future |
| f | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| function call | now | now |
| f() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.call() | now | now |
| f.apply() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.bind() | future | now |
| | | |
+-------------------+-------------------+-------------------+
我也想知道为什么示例 3 解决了这个问题以及示例 2 和 3 之间的区别。
示例 1/2 和 3 截然不同。 并包含函数,这些函数在将来调用,而包含当时调用的结果。storeMyName
storeMyName2
storeMyName3
myName.getName()
延伸阅读材料:
评论
myName.getName()
this
myName
myName.getName.call(myName)
Bind 是一种机制,通过该机制,您可以更改执行的上下文(此处的默认上下文是全局上下文)。
根据您的示例 -
var storeMyName = myName.getName;
从上面的一行是你正在全局上下文中执行函数,所以对于这个执行将是顶行(即全局一/“约翰”)。storeMyName
this.name
var storeMyName2 = myName.getName.bind(myName);
对于上面的一行,您正在显式更改函数的执行上下文(通过说我不想将此函数作为全局函数执行,我想在对象的上下文中执行此函数,因此在这种情况下将是“Tom”)storeMyName2
myName
this.name
var storeMyName3 = myName.getName(); // example 3
对于上面的这一行,你只是在对象上下文上执行函数,更重要的是你没有执行,这就是为什么它的上下文不是全局的。myName
storeMyName3
我喜欢一个类比,我从未在任何地方见过:
假设你有一个带有函数的 foo 对象。
当您将 bar 函数绑定到另一个变量(或将其作为函数参数传递,这在回调中更常见)时,您不是将函数与他的封闭对象绑定/传递,而只是“裸体”函数。
因此,使用“裸体”函数,表示全局对象。bar
this
一个小演示
var foo = "global foo"; //foo set on the global object
var a = {foo : "object foo", bar : function(){return this.foo;}};
var bound = a.bar;
console.log(bound());//returns "global foo", not "object foo"
bound
只需指向function(){return this.foo;}
评论
其
工作原理。this
storeMyName
storeMyName2
storeMyName3
myName.getName()
.bind
this