为什么JavaScript bind()是必需的?

问题描述:

示例1中的问题是'this'引用全局名称而不是myName对象。为什么JavaScript bind()是必需的?

我明白使用bind()将它的值设置为特定的对象,所以它解决了示例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

+2

* “是不是刚刚的Javascript创建的方式是什么?” *我想是的。 “this”的值是动态确定的,除非它是绑定或箭头函数。不知道你想知道还有什么期望[学习如何'这个'工作](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes /ch1.md)。 –

+0

[Javascript call()&apply()vs bind()?](http://*.com/questions/15455009/javascript-call-apply-vs-bind) – azad

+3

*“我也想知道为什么示例3解决了问题“*'storeMyName'和'storeMyName2'包含* functions *,而'storeMyName3'包含调用*'myName.getName()'的*结果*。巨大差距。我在调用函数和'.bind'的方法之间进行了这种比较:https://twitter.com/fkling42/status/736228742008176640。也许它有助于某种方式。 –

为什么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不可能有更大的不同。 storeMyNamestoreMyName2包含函数,这在将来被调用,而storeMyName3包含在那一刻调用myName.getName()的结果


进一步阅读材料:

+0

非常感谢您的帮助和资源。我是JavaScript新手,你对我的回答非常明显。所以call()/ apply()与例3相同,除了getName()方法与对象分离时使用。 –

+0

基本上是的。如果一个函数是一个对象的属性,那么将该函数调用为myName.getName()将隐式地将this设置为myName。它相当于'myName.getName.call(myName)'。 –

bind()方法创建,调用它时的新功能,将其关键字设置为提供的值,并在调用新函数时提供的任何参数序列之前提供给定的参数序列。

所以,当你执行var storeMyName = myName.getName;第一次,它需要全球name(this.name =“约翰”)

当您使用bind()功能,它开始参照当前定义的名称封闭件(MYNAME在这种情况下),因此打印Tom

第三时间,因为该函数被调用马上其范围是其自身的本地对象物的内部,从而在闭合打印值Tom

绑定是机制,通过它可以更改执行的上下文(这里您的默认上下文是全局的)。

根据你的榜样 -

var storeMyName = myName.getName; 

从上面一行是要执行在全球范围内storeMyName功能,所以这个执行this.name将顶线(即全球性的/“约翰”)。

var storeMyName2 = myName.getName.bind(myName); 

对于上述行你明确改变执行上下文storeMyName2功能(说,我不想执行此功能作为全局函数我想在myName对象的上下文中执行此功能,所以在这种情况下this.name将是“汤姆”)

var storeMyName3 = myName.getName(); // example 3 

而对于这个上面一行你只是执行上myName对象上下文的功能,更重要的是你是不是在执行storeMyName3,这就是为什么它的背景不是全球性的。

我喜欢的一个比喻,我从来没有见过任何地方: 假设你有一个具有bar函数的foo对象。 当您将bar函数绑定到另一个变量(或将其作为函数参数传递时,这对于回调来说更常见),您不是将函数与其封闭对象进行绑定/传递,而只是“nude”函数。 因此,使用“裸体”功能,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;}