Nodejs中理解bind函数方法的迷惑之处,求大神指导

Nodejs中理解bind函数方法的迷惑之处,求大神指导

var someuser = {
name: ‘byvoid’,
func: function () {
console.log(this.name);
}
};
var foo = {
name: ‘foobar’
};
func = someuser.func.bind(foo);
func(); // 输出 foobar
func2 = func.bind(someuser);

func2(); // 输出 foobar

括号里面这个地方就是不明白的地方 为什么没有变


4 回复

当然可以。让我们详细解释一下 bind 函数的作用以及为何在你的例子中 func2() 输出的是 “foobar” 而不是 “byvoid”。

Node.js 中的 bind 函数

bind 函数用于创建一个新的函数,当调用这个新函数时,它会使用指定的 this 值,并且可以预设一些参数。

示例解析

首先,我们来看一下你的代码:

var someuser = {
  name: 'byvoid',
  func: function () {
    console.log(this.name);
  }
};

var foo = {
  name: 'foobar'
};

// 将 someuser.func 绑定到 foo 对象上
var func = someuser.func.bind(foo);
func(); // 输出 foobar

// 将 func 绑定到 someuser 对象上
var func2 = func.bind(someuser);
func2(); // 输出 foobar

逐行解释

  1. 定义对象 someuserfoo

    var someuser = {
      name: 'byvoid',
      func: function () {
        console.log(this.name);
      }
    };
    
    var foo = {
      name: 'foobar'
    };
    

    这里定义了两个对象 someuserfoo,分别具有不同的 name 属性。

  2. someuser.func 绑定到 foo 对象

    var func = someuser.func.bind(foo);
    

    使用 bind 方法将 someuser.functhis 上下文绑定到 foo 对象上。这意味着当 func 被调用时,this 指向 foo,而不是 someuser

  3. 调用 func()

    func(); // 输出 foobar
    

    因为 func 现在指向一个绑定了 foo 的函数,所以 this.name 实际上是指向 fooname 属性,即 "foobar"

  4. func 绑定到 someuser 对象

    var func2 = func.bind(someuser);
    

    这里你尝试将已经绑定到 foofunc 再次绑定到 someuser。然而,bind 返回的是一个新的函数,不会改变已经绑定的上下文。因此,即使你再次调用 bindfunc 仍然会保持其之前绑定的上下文(即 foo)。

  5. 调用 func2()

    func2(); // 输出 foobar
    

    由于 func 已经绑定到 foo,即使你通过 func2 = func.bind(someuser) 创建了一个新的绑定,func2 依然会输出 fooname 属性 "foobar",而不是 someusername 属性 "byvoid"

总结

bind 方法一旦被应用,就会锁定 this 上下文,后续的 bind 调用不会改变已经绑定的上下文。因此,在你的例子中,无论你如何重新绑定 func,它始终会输出 fooname 属性 "foobar"


because nested closure.


签名: 交流群244728015 《Node.js 服务器框架开发实战》 http://url.cn/Pn07N3

thank you~

bind 方法会创建一个新的函数,并将其中的 this 值绑定到传给 bind 的第一个参数。即使后续再次调用 bind 方法改变了传递的上下文对象,原绑定的 this 值也不会改变。

示例代码中的 funcsomeuser.func 绑定到 foo 对象后的结果。因此无论之后如何重新绑定 func,它内部的 this 值依然指向 foo 对象,而不是最后一次绑定的对象。

具体解释如下:

var someuser = {
  name: 'byvoid',
  func: function () {
    console.log(this.name); // this 指向调用该函数时的上下文对象
  }
};

var foo = {
  name: 'foobar'
};

// 将 someuser.func 绑定到 foo 对象
var func = someuser.func.bind(foo);

// 输出 foobar
func();

// 将 func 重新绑定到 someuser 对象,但 func 的 this 值不会改变
var func2 = func.bind(someuser);

// 仍然输出 foobar,因为 func 的 this 值已经固定为 foo
func2();

在这个例子中,func 已经被绑定到 foo 对象,所以 func2 的执行结果依然是 foobar

回到顶部