call, apply, bind的区别

235 阅读2分钟

call, apply, bind都可以改变函数的this的指向,那么接下来就讲解一下这3者的区别

call语法

fun.call(thisArg, arg1,arg2, ...)
thisArg: 指在fun函数运行时执行的this,即在fun函数最外层打印出来的this指向thisArg,这样就给fun函数绑定了thisArg;
arg1, arg2, ... : 表示要传的多个参数;
列子:

var cat = {
	name: '小红',
    eatFish(...args) {
    	console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃鱼');
    }
}
var dog = {
	name: '大龙',
    eatBone(...args) {
    	console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃骨头');
    }
}
// 有一天大龙想吃鱼了,可是不懂怎么去吃鱼,怎么办呢?小红就说等会我吃的时候我喂你吃
cat.eatFish.call(dog, '汪汪汪', 'call');
// 为了感谢小红,大龙决定下次他吃骨头的时候也喂小红吃
dog.eatBone.call(cat, '喵喵喵', 'call');

apply语法

fun.apply(thisArg, [argsArray])
thisArg: 在fun函数运行时指定的this,即在fun函数最外层打印出来的this指向thisArg,这样就给fun函数绑定了thisArg;
argsArray: 所需要的传的参数,以数组的形式传;
注意: apply与call的区别是参数的传递形式不一样,call的多个参数是以逗号分隔直接传的,而apply的多个参数是以数组的形式传的。

cat.eatFish.apply(dog, ['汪汪汪', 'call']);
dog.eatBone.apply(cat, ['喵喵喵', 'call']);

bind语法

fun.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg: 在fun函数运行时指定的this,即在fun函数最外层打印出来的this指向thisArg,这样就给fun函数绑定了thisArg;
arg1, arg2, ... : 表示要传的多个参数;

const test1 = cat.eatFish.bind(dog, ['汪汪汪', 'call']);
const test2 = dog.eatBone.bind(cat, ['喵喵喵', 'call']);
test1();
test2();

区别

apply与call的区别是参数的传递形式不一样,call的多个参数是以逗号分隔直接传的,而apply是以一个数组的形式传递的,就算是一个参数也是以一个数组的形式传递的。
而bind是直接改变了this的指向,指向了一个新的函数,并返回这个新的函数。每次调用这个函数的时候this都是指向bind绑定的第一个参数,bind的传参方式和call的一致。

扩展知识

由与apply的特殊性,我们可以通过Math.max.apply()得到一个数组的最大的一项,如下所示:

const max = Math.max(1,2,3);
console.log(max); // 3

const max2 = Math.max.apply(null, [1,2,3]);
console.log(max2); // 3

bind也有一个小技巧,传参的技巧,如下所示:

// 将某个函数的this指向改变,绑定新的this指向,并且在绑定的时候固定的传入几个参数,
// 之后调用新的函数的时候可以再传几个参数进来,排在固定参数后面
const obj = {};
function testFun(...args) {
	console.log(args);
}
const newFun = testFun(obj, '静态参数1', '静态参数2');
newFun('动态参数1', '动态参数2'); // ['静态参数1', '静态参数2', '动态参数1', '动态参数2']

如图所示: