call, apply, bind 的区别 javascript
- call、apply、bind这3个都可以改变this指向
- call和apply都接收2个参数,第一个参数是this指向的对象,一般null就代表this指向window,第二个参数是给方法传递的参数,二者区别是第二个传参格式的不同,call传参是分开传的,apply传参是一个数组。如:
obj.call(sobj, '学习C语言','学习数据结构')
,obj.apply(sobj, ['学习C语言', '学习数据结构'])
,看到区别了吧 - call和apply 只是第二个参数传参格式不同,二者主要区别于bind的是,bind会返回一个函数,不会立马执行,而call和apply会立马执行;bind的参数格式和call的参数格式是一样的。
- 由于apply的第二个参数是一个数组,
apply
通常可以用在以下2种情况:Array.prototype.push(a, b)
,这个是用于数组合并,将b数组合并到a数组中,还可以写成:a.push.apply(a, b)
Math.max.apply(null, arr)
,这个是用于找出一个数字数组的最大值,因为不需要this指向替换,所以apply
第一参数是null
,第二个参数arr是数字数组。
- 例子,接下来的例子会基于这2个对象:
var obj = {
study: 'Java',
days: '3h',
getStudy: function() {
console.log(this)
console.log(this.study + '学习' + this.days)
}
}
var sobj = {
study: 'C#',
days: '4h'
}
- 直接使用getStudy()
obj.getStudy() // 输出:obj本身的属性值
结果:
- 使用call改变this指向
obj.getStudy.call(sobj) // 输出:sobj的属性值,改变this指向为sobj
结果:
- 使用apply改变this指向
obj.getStudy.apply(sobj)
结果输出:
4. 第二个参数传参方式不同,call和apply的传参格式
var obj = {
study: 'Java',
days: '3h',
getStudy: function(collage, name) {
console.log(this)
console.log(collage + '的学生' + name + '学习' + this.study + '花费了' + this.days)
}
}
var sobj = {
study: 'C#',
days: '4h'
}
obj.getStudy.apply(sobj, ['郑州大学', '李燕']) // apply的传参是数组格式
console.log('---------------------------------------')
obj.getStudy.call(sobj, '郑州大学', '李燕') // call的传参是分开传参
输出结果:
- 使用例子4的代码,bind改变this指向
let bindFun = obj.getStudy.bind(sobj) // bind返回一个函数,将这个函数赋值给一个变量
bindFun('郑州大学', '李燕') // 执行, 传参格式和call的第二个传参格式是一样的,是分开传参的
还可以就将参数一起写入,这2种写法都可以:
let bindFun = obj.getStudy.bind(sobj, '郑州大学', '李燕')
bindFun()
结果输出: