JasmineHua's blog

javascript中call,apply,bind的使用方法

前言

call,apply,bind用法十分相似容易混淆。网上文章虽多,但大多晦涩难懂。
在看此篇文章前建议先看另一篇javascript中this的指向,便于对call,apply,bind理解

call()方法和apply()方法

call()和apply()

call()和apply()的第一个实参是要调用函数的母对象,他是调用上下文,在函数体内通过this来获得对它的引用。即call()和apply()的第一个实参都会变为this的值。要想以对象o的方法来调用函数f():

1
2
f.call(o)
f.apply(o)

等价于

1
2
3
o.m = f //将f储存为o的临时方法
o.m() //调用这个方法。
delet o.m //删除方法

举个例子

1
2
3
4
function f(){return this.x} //创建函数f
var o = {x:1} //创建对象o
f.call(o) //=> 1:对象o为调用的上下文,函数f内this指向o。
f.apply(o) //同上

call()和apply()的区别

当call()和apply()传入多个参数时,apply()方法和call()虽类似,但传入实参的形式和call()有所不同,它的实参是放在数组中的:

1
2
f.call(o,1,2)
f.apply(o,[1,2])

例如,为了找出数组中最大的值,调用Math.max()方法的时候可以给apply()传入一个数组

1
var maxInNumbers = Math.max.apply(Math, [6, 123, 111 , -555]) //=>123

bind()方法

bind()

这个方法的主要作用是将函数绑定至某个对象。当函数f()调用bind()方法传入参数o,这个方法将返回一个新的函数,这个函数内的this值指向o。调用这个新的函数会吧函数f()当作o的方法调用
举例说明:

1
2
3
4
5
function f(y){return this.x} //创建函数f
var o = {x:1} //创建对象o
var g = f.bind(o) //将函数f()绑定至对象o
console.log(g) //=>function f(){return this.x}
g() //=>1:this指向对象o,传入参数2

1
2
3
4
function f(y,z){return this.x+y+z}
var o = {x:1}
var g = f.bind(o)
g(2,3) //=>6

bind()方法还有一些其他应用。除了第一个参数外,传入bind()的实参也会绑定至this,这个应用被称为“柯里化(currying)”:

1
2
3
4
function f(y,z){return this.x+y+z}
var o = {x:1}
var g = f.bind(o,2) //绑定this和y
g(3) //=>6

bind()和call(),apply()的区别

由上述例子就可以看出bind()和call(),apply()返回值的区别。
将例子整合后比较如下:

1
2
3
4
5
6
function f(){return this.x} //创建函数f
var o = {x:1} //创建对象o
f.call(o) //=> 1:对象o为调用的上下文,函数f内this指向o。
f.apply(o) //同上
f.bind(o) //=>function f(){return this.x}
f.bind(o)() //=> 1

总结一下

  1. apply()、call()、bind()三者都是用来改变函数的this指向的;
  2. apply()、call()、bind()三者第一个参数都是this要指向的对象,也就是调用的上下文;
  3. apply()、call()、bind()三者都可以利用第一个参数以后的参数传参;
  4. bind()是返回对应函数,便于稍后调用;apply()、call()则是立即调用 。