为什么JavaScript bind()是必需的?
示例1中的问题是“this”指的是全局名称,而不是myName对象 我理解bind()在将其值设置为特定对象时的用法,因此它解决了示例1中的问题,但为什么首先会出现这个问题?这就是Javascript的创建方式吗 我还想知道为什么示例3解决了这个问题,以及示例2和示例3之间的区别为什么JavaScript bind()是必需的?,javascript,this,bind,Javascript,This,Bind,示例1中的问题是“this”指的是全局名称,而不是myName对象 我理解bind()在将其值设置为特定对象时的用法,因此它解决了示例1中的问题,但为什么首先会出现这个问题?这就是Javascript的创建方式吗 我还想知道为什么示例3解决了这个问题,以及示例2和示例3之间的区别 this.name=“John” var myName={ 姓名:“汤姆”, getName:function(){ 返回此名称 } } var storeMyName=myName.getName;//例1 var
this.name=“John”
var myName={
姓名:“汤姆”,
getName:function(){
返回此名称
}
}
var storeMyName=myName.getName;//例1
var storeMyName2=myName.getName.bind(myName);//例2
var storeMyName3=myName.getName();//例3
log(“示例1:+storeMyName());//不起作用
log(“示例2:+storeMyName2());//作品
log(“示例3:+storeMyName3);//作品
bind()
方法创建一个新函数,在调用该函数时,将其this关键字设置为提供的值,并在调用新函数时提供的任何参数之前提供给定的参数序列
因此,当您执行var storeMyName=myName.getName第一次使用全局名称(this.name=“John”)
当您使用bind()
函数时,它开始引用当前闭包中定义的名称(本例中为myName),并因此打印Tom
第三次,由于函数立即被调用,它的作用域在它自己的局部对象内,因此在闭包Tom
为什么JavaScript bind()是必需的
此
的值由函数的调用方式决定。如果是您调用该函数,则通常不需要使用.bind
,因为您可以控制如何调用该函数,从而控制其值
但是,调用函数的通常不是您。函数作为回调和事件处理程序传递给其他函数。它们由其他代码调用,您无法控制函数的调用方式,因此无法控制此
将引用的内容
如果您的函数要求将this
设置为特定值,而您不是调用该函数的人,则需要。将函数绑定到特定的this
值
换句话说:.bind
允许您设置此
的值,而无需立即调用函数
以下是引用/调用函数的比较:
+-------------------+-------------------+
| | |
| 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()
的结果
进一步阅读材料:
绑定是一种机制,通过它您可以更改执行的上下文(这里您的默认上下文是全局上下文)
根据你的例子-
var storeMyName = myName.getName;
从上面的一行可以看出,您正在全局上下文中执行storeMyName
函数,因此对于此执行this.name
将是最上面的一行(即global one/“John”)
对于上面的一行,您正在显式地更改storeMyName2
函数的执行上下文(通过说我不想作为全局函数执行此函数,我想在myName
对象的上下文中执行此函数,所以在这种情况下,this.name
将是“Tom”)
对于上面这一行,您只是在myName
对象上下文上执行函数,更重要的是,您没有执行storeMyName3
,这就是它的上下文不是全局上下文的原因。一个我喜欢的类比,我在任何地方都没有见过:
假设您有一个带有bar
函数的foo对象。
当您将bar函数绑定到另一个变量(或将其作为函数参数传递,这在回调中更常见),您没有绑定/传递带有其封闭对象的函数,而只绑定/传递“裸”函数。
因此,对于“裸”函数,表示全局对象
小型演示
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
只要指向函数(){return this.foo;}
“这就是创建Javascript的方式吗?”我想是的。此
的值是动态确定的,除非它是绑定函数或箭头函数。不确定您还想知道什么。可能重复的“我也想知道为什么示例3解决了这个问题”storeMyName
和storeMyName2
包含函数,而storeMyName3
包含调用myName.getName()
的结果。差别很大。我比较了调用函数的方式和.bind
:。也许这会有所帮助。这是一本很棒的书。它在JS中为我澄清了关于这个
的一切:非常感谢你的帮助和资源。我是javascript新手,你给了我一个很明显的答案。因此call()/apply()与示例3相同,只是在getName()方法与对象分离时使用?基本上是的。如果函数是对象的属性,则以myName.getName()
的形式调用该函数将隐式地将this
设置为myName
。它相当于myName.getName.call(myName)
。
var storeMyName3 = myName.getName(); // example 3
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"