JavaScript 中 call()、apply()、bind() 的用法与区别
在js的开发当中,会经常使用到call()
、apply()
、bind()
这三个函数,这三个函数到底是干嘛的呢?
其实很简单,这其中最主要的区别是this
的指向问题,这三个函数都是改变函数内部Function
的this
指向。
首先,我们先看一下下面的例子:
// 例子一
var myDog = 'tom'
var isObj = {
name: this.myDog,
color: 'red',
itSay: function () {
console.log('my name is ' + this.myDog + ', color is ' + this.color)
}
}
console.log(isObj.name) // tom
console.log(isObj.itSay()) // my name is undefined, color is red
我们可以看到上面的打印区域,isObj.name
打印出来是tom
,但是下面itSay()
打印输出undefined
。因为在上面打印之中this
指向的是window
对象,myDog
是一个全局变量,相当于isObj.name = window.myDog
所以输出tom
,但是在函数里面,这个this
指向的是isObj
这个对象,所以不存在myDog
属性,所以是undefined
。
再看一个例子:
// Function.prototype.call()
var myDog = 'tom'
var isObj = {
name: this.myDog,
color: 'red',
itSay: function () {
console.log('my name is ' + this.name + ', color is ' + this.color)
}
}
var testObj = {
name:'jarry'
}
var testObjs = {
name:'jarry',
color:'gray'
}
isObj.itSay.call(testObj) // my name is jarry, color is undefined
isObj.itSay.call(testObjs) // my name is jarry, color is gray
其实可以看出call()
方法就是把this
指向参数里面的对象,没有的属性打印就显示undefined
,我们再看一下剩余的两个函数。
// 例子三
var myDog = 'tom'
var isObj = {
name: this.myDog,
color: 'red',
itSay: function (age, ...args) {
console.log('my name is ' + this.name + ', color is ' + this.color + ' my age is ' + age+ 'years old, ' + args)
}
}
var testObjs = {
name:'jarry',
color:'gray'
}
isObj.itSay.call(testObjs,'8','ba','la','ba','la') // my name is jarry, color is gray my age is 8, ba,la,ba,la
isObj.itSay.apply(testObjs,['8','ba','la','ba','la']) // my name is jarry, color is gray my age is 8, ba,la,ba,la
isObj.itSay.bind(testObjs,'8','ba','la','ba','la')() // my name is jarry, color is gray my age is 8, ba,la,ba,la
可以看出,这三个函数都打印出同样的文字, bind()
绑定的是一个函数需要调用一下,使用方法和cell()
一样,apply()
其最后面的参数接收一个数组传值,他们的第一个参数都是this
,可以省略不传。
从上面结果不难看出:
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 isObj.itSay.call(db,'成都', ... ,'string' )
。
apply ()
的所有参数都必须放在一个数组里面传进去 isObj.itSay.apply(db,['', ..., 'string' ])
。
bind()
除了返回是函数以外,它 的参数和 call()
一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!