为什么JavaScript必须绑定()?

例1中的问题是'this'引用全局名称而不是myName对象。

我理解使用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

为什么JavaScript必须绑定()?

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和3不能有更多的不同。 storeMyNamestoreMyName2包含将来调用的函数,而storeMyName3包含此时调用myName.getName()的结果。


更多阅读材料:

  • “this”关键字如何工作?
  • MDN - 这个
  • YDKS - 这个&对象原型
  • 如何在回调中访问正确的`this`上下文?

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

    所以,当你执行var storeMyName = myName.getName; 第一次,它采用全球name (this.name =“John”)

    当你使用bind()函数时,它开始引用在当前闭包中定义的名称(在这种情况下是myName),因此打印Tom

    第三次,因为该函数马上被调用,所以它的作用域在它自己的本地对象内,因此在关闭Tom打印该值


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

    根据你的例子 -

    var storeMyName = myName.getName;
    

    从上面来说,你是在全局上下文中执行storeMyName函数的,所以对于这个执行, this.name将是最上面的一行(即全局一个/“John”)。

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

    对于上面的行,你显式地改变了storeMyName2函数的执行上下文(通过说我不想执行这个函数作为全局函数,我想在myName对象的上下文中执行这个函数,所以在这种情况下this.name会是“汤姆”)

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

    对于上面这行,你只是在myName对象上下文上执行函数,更重要的是你没有执行storeMyName3 ,这就是为什么它的上下文不是全局的。

    链接地址: http://www.djcxy.com/p/96995.html

    上一篇: Why is JavaScript bind() necessary?

    下一篇: Javascript event handler with parameters