在面试中经常会被问到call、apply、bind三者的用法和区别,今天就来整理一下!
我们知道,call、apply、bind这三兄弟都是可以改变this指向的,那具体如何使用呢?
我们先定义两个对象
var obj={
name:'Li lei',
age:18,
intr:function(){
console.log(`我叫${this.name},我${this.age}岁`);
}
}
var obj2={
name:'Han meimei',
age:20,
intr:function(){
console.log(`I'm ${this.name},I'm ${this.age} years old`);
}
}
obj.intr(); //我叫Li lei,我18岁
obj2.intr(); //I'm Han meimei,I'm 20 years old
当我们调用obj和obj2中的intr方法时,输出的是各自对象中的name和age,如果我们需要使用obj中的参数执行obj2的intr方法,就可以使用call、apply、bind实现
先看一下call
obj.intr.call(obj2); //我叫Han meimei,我20岁
obj2.intr.call(obj); //I'm Li lei,I'm 18 years old
由上可知,当执行第一句时,obj.intr中的this指向发生了改变,指向了obj2
同理,当执行第二句时,obj2.intr中的this指向了obj
再来看看apply和bind
obj.intr.apply(obj2); //我叫Han meimei,我20岁
obj.intr.bind(obj2)(); //我叫Han meimei,我20岁
可以看到这里apply和call是一样的,但是bind返回的是一个函数,所以需要调用后才执行intr方法
三者传参的区别
我们将之前的例子修改一下
var obj={
name:'Li lei',
intr:function( age, city ){
console.log(`我叫${this.name},我${age}岁,我来自${city}`);
}
}
var obj2={
name:'Han meimei',
intr:function( age, city ){
console.log(`I'm ${this.name},I'm ${age} years old,I'm from ${city}`);
}
}
obj.intr.call( obj2, 20, '中国' ); //我叫Han meimei,我20岁,我来自中国
obj.intr.apply( obj2, [ 20, '中国' ] ); //我叫Han meimei,我20岁,我来自中国
obj.intr.bind( obj2, 20, '中国' )(); //我叫Han meimei,我20岁,我来自中国
可以看到call和bind都是独立传递,而apply是以数组传递参数的,参数也可以是方法或对象
总结
call、apply、bind可以将某个函数的this指向修改为传入这三个方法中的第一个参数,其中call、apply会立即执行,bind返回的是一个函数,需调用后执行。
第二个参数是传入要执行的方法中的参数,call、bind是独立传递参数,apply是以数组传递参数的
使用场景:
1、需要改变某个函数的this指向时
2、当参数较少时可以使用call,参数较多可以使用apply以数组的方式传递
3、当需要重复调用时,可以使用bind新定义一个方法