面向对象 - bind

bind 方法用于将函数体内的 this 绑定到某个对象,然后返回一个新函数

var d = new Date()
d.getTime() // 1578380274914

var print = d.getTime
print() // TypeError: this is not a Date object.

上面代码中,我们将 d.getTime 方法赋给变量 print,然后调用 print 就报错了。这是因为 getTime 方法内部的 this,绑定 Date 对象的实例,赋给变量 print 以后,内部的 this 已经不指向 Date 对象的实例了

bind 方法可以解决这个问题

var print = d.getTime.bind(d)
print() // 1578380274914

上面代码中,bind 方法将 getTime 方法内部的 this 绑定到 d 对象,这是就可以安全地将这个方法赋值给其他变量了

bind 方法的参数就是所要绑定 this 的对象,下面是一个更清晰的例子

var counter = {
  count: 0,
  inc: function() {
    this.count++
  }
}

var func = counter.inc.bind(counter)
func()
counter.count // 1

上面代码中,counter.inc 方法被赋值给变量 func。这时必须用 bind 方法将 inc 内部的 this,绑定到 counter,否则就会出错

this 绑定到其他对象也是可以的

上面代码中,bind 方法将 inc 方法内部的 this,绑定到 obj 对象。结果调用 func 函数以后,递增的就是 obj 内部的 count 属性

bind 还可以接受更多的参数,将这些参数绑定原函数的参数

上面代码中,bind 方法除了绑定 this 对象,还将 add 函数的第一个参数 x 绑定成 5,然后返回一个新函数 newAdd,这个函数只要再接受一个参数 y 就能运行了

如果 bind 方法的第一个参数是 null 或 undefined,等于将 this 绑定到全局对象,函数运行时 this 指向顶层对象(浏览器为 window)

代码上面中,函数 add 内部并没有 this,使用 bind 方法的主要目的是绑定参数 x,以后每次运行新函数 plus5,就只需要提供另一个参数 y 就能运行了

如果 bind 方法的第一个参数是 null 或者 undefined,等于将 this 绑定到全局对象,函数运行时 this 指向顶层对象(浏览器为 window

上面代码中,函数 add 内部并没有 this,使用 bind 方法的主要目的是绑定参数 x,以后每次运行新函数 plus5,就只需要提供另一个参数 y 就足够了。而且因为 add 内部没有 this,所以 bind 的第一个参数是 null,不过这里如果是其他对象,也没有影响

bind 方法有一些使用注意点

每一次返回一个新函数

bind 方法没运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样

上面代码中,click 事件绑定 bind 方法生成的一个匿名函数。这样会导致无法取消绑定,所以,下面的代码时无效的。

正确的方法时写成下面这样:

结合回调函数使用

回调函数时 JavaScript 最常用的模式之一,但是一个常见的错误是,将包含 this 的方法直接当作回调函数。解决方法就是使用 bind 方法,将 counter.inc 绑定 counter

上面代码中,callIt 方法会调用回调函数。这是如果直接把 counter.inc 传入,调用时 counter.inc 内部的 this 就会指向全局对象。使用 bind 方法将 counter.inc 绑定 counter 以后,就不会有这个问题,this 总是指向 counter

Last updated

Was this helpful?