call/apply/bind的使用方法和区别
相同点
- 第一个参数都是this要指向的对象
- 这三个方法是函数方法,除了箭头函数之外都可以调用
- 改变this指向
- 至少有一个参数
区别
call:有多个参数,除第一个参数是this要指向的对象外,其余参数都是该函数需要的参数,且至少有一个参数
apply:有两个参数,除第一个参数是this要指向的对象外,第二个参数是数组 且至少有一个参数
bind:bind返回的是一个函数
示例:
<script>
const obj1 = {
name: 'jack'
}
const obj2 = {
name: 'rose'
}
function hi(msg1, msg2) {
console.log(`${msg1}+${msg2}+${this.name}`)
// 打印结果
// 18+好看+rose
// 19+漂亮+rose
// 20+帅+jack
}
hi.call(obj2, 18, '好看')
hi.apply(obj2, [19, '漂亮'])
const hiBind = hi.bind(obj1)
hiBind(20, '帅')
</script>
注意:
看到代码示例,我们首先应该想到的是在hi这个函数中,我们打印的this.name的this指向的是谁,在没有调用方法的时候,显而易见this指向的是window,但是window里面没有name这个属性,在这个时候,我们就需要通过改变This指向,来获取我们想要的属性
三种方法的使用场景
- bind使用场景:
在使用回调函数的时候,可以使用bind方法,在这里我们展示的回调函数是setTimeout方法,setTimeout方法中有callback,这个callback会改变this的指向,所以,我们在使用setTimeout方法的时候,需要绑定bind方法,来帮助我们将this指向我们需要的对象,获取我们想要的函数
示例:
let o = {
name: 'test',
fn() {
console.log(this)
console.log(this.name)
}
}
setTimeout(o.fn.bind(o), 0)
- apply使用场景: 在前端拿到的数据为数组时,调用apply方法会更方便我们获得需要的对象和参数
//第一种
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
//第二种
//**获取数组中的最大值和最小值**
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
- 使用场景:
//**获取数组中的最大值和最小值**
var maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
//第二种:
var a = Object.prototype.toString;
console.log(a.call("aaa"));
console.log(a.call(1));
console.log(a.call(true));
console.log(a.call(null));
console.log(a.call(undefined));
console.log(a.call([]));
console.log(a.call(function() {}));
console.log(a.call({}));