前言
apply、bind、call大家在初次见到的的时候难免会疑惑,好纠结呀,都没用过。我可以告诉大家,咱们就学一个,学会这一个,其他两个就迎刃而解了。咱就学call,call学完其他两个就简单了。
什么是call
call是一个方法,它是函数的方法。我们来看以下代码:
function fun() {
console.log("hello world")
};
// call可以调用方法
fun.call();
输出为:
我们可以看到call直接被调用了。说明函数的call方法可以直接调用函数。
除了可直接被调用往外,call还可以改变this指向,我们来看以下代码:
function fun() {
console.log(this)
console.log(this.name);
};
let cat = {
name: "喵喵"
}
fun(); // 空
//call可以改变函数中this 指向
fun.call(cat); // 喵喵
我们可以看到第一次打印出来的结果是:this是指Window,this.name打印出来是空
第二次call运行输出的结果是:this指向的是cat对象,this.name打印出来是喵喵(cat的属性)
call深入了解
this指向修改
接下来我们实现一个this指向的更改,我们来看以下代码:
let dog = {
name: "旺财",
sayName() {
console.log("我是" + this.name);
}
}
let cat = {
name: "喵喵"
}
// call可以调用函数,cal1可以改变函数中this
//指向
dog.sayName() // 我是旺财
dog.sayName.call(cat); // 我是喵喵
输出为:
我们可以看到当sayName方法被直接调用时,输出为我是旺财
当我们用call方法把this指向更改为cat的时候,sayName方法就输出为我是喵喵
call的其他传参
我们在dog对象中新添加一个方法eat:
eat(food) {
console.log('吃' + food)
}
正常调用的话:
dog.eat('骨头') // 吃骨头
如果换成call调用我们就需要将传入的参数作为第二参数传入如下:
dog.eat.call(cat,'鱼'); // 吃鱼
当我们有更多参数时候,我们可以在call方法的 2、3、4...n个参数中传入:
dog.eat.call(cat,'鱼','老鼠'); // 吃鱼、老鼠
所以call的第一个参数为改变this指向的对象,第2到n个参数为所传得参数
apply、bind、call的区别
apply的参数列表是数组传入的,具体用法如下:
dog.eat.apply(cat,['鱼','老鼠']); // 吃鱼、老鼠
bind和call的区别在于bind不会直接调用方法,方法将是它的一个返回:
let fn = dog.eat.bind(cat,'鱼','老鼠');
fn(); // 吃鱼、老鼠
整理下这三者的区别在于:
| 区别项 | apply | bind | call |
|---|---|---|---|
| 第2参数 | 数组 | 按参数传 | 按参数传 |
| 方法调用 | 立即调用 | 返回方法 | 立即调用 |