更改this指向用call、apply、bind就对了
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
let obj = {a:1}
function fun(a,b,c){
console.log(this.a);
console.log(a,b,c);
}
fun.call(obj,3,4,5);
fun.apply(obj,[3,4,5]);
fun.bind(obj,3,4,5)();
一.什么时候需要更改this指向
首先举个例子:
let apple = {
name: 'apple',
say: function () {
console.log(this.name);
}
}
apple.say();//apple
let banana = {
name: 'banana'
}
在上面这个例子中,如果我们新建一个对象,但是又不想再重写say()方法怎么办呢?这个时候我们就需要更改this指向.如下:
apple.say.call(banana);//banana
apple.say.apply(banana);//banana
那么上面的例子中,我们就是将apply对象中say()方法中的this指向了banana对象,这样就能在不重写say()方法的前提下直接使用这个方法.
二.call、apply异同
还是刚才的例子:
let apple = {
name: 'apple',
say: function (color1, color2) {
console.log(this.name + '的颜色有' + color1 + '、' + color2);
}
}
apple.say('红色', '绿色');//apple的颜色有红色、绿色
let banana = {
name: 'banana'
}
apple.say.call(banana, '黄色', '绿色');//banana的颜色有黄色、绿色
apple.say.apply(banana, ['黄色', '绿色']);//banana的颜色有黄色、绿色
apple.say.bind(banana, '黄色', '绿色')();//banana的颜色有黄色、绿色
通过例子可以知道,apply和call作用是一样的它们的区别是:call传入参数时用逗号隔开,而apply需要使用数组接收参数并传入.
它们和bind的区别是:在更改this指向的同时调用这个方法.
另外apply可以改变传递给函数参数的形式,如常见用法二的例子,即:
obj.function.call(this,arg1,arg2);
obj.function.apply(this,[arg1,arg2]);
三.apply、call常见的一些用法
通过apply拼接两个数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);//[1, 2, 3, 4, 5, 6]
通过apply、call获取数组的最大/最小值(这个挺骚的)
let arr1 = [1, 2, 3];
console.log(Math.min.apply(this, arr1));//1
console.log(Math.max.apply(this, arr1));//3
console.log(Math.min.call(this, 2, 5, 7, 9));//2
console.log(Math.max.call(this, 2, 5, 7, 9));//9