文章目录
一.什么时候需要更改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常见的一些用法
1.通过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]
当然也可以直接使用concat
拼接多个数组
let arr3 =arr1.concat(arr2);
console.log(arr3);//[1, 2, 3, 4, 5, 6]
2.通过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
3.代理console.log方法
function log(msg){
console.log(msg);
}
log(1);//1
log(1,2);//1
当上面msg
传入的参数不确定的时候,我们可以使用apply
来解决这个问题.
function log(){
console.log.apply(this,arguments)
}
log(1);//1
log(1,2);//1 2
四.bind
bind
也和call apply
一样,都是可以更改this
的指向.bind
需要调用才行.即:
obj.function.bind(this,arg1,arg2)();
五.总结
-
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的; apply 、 call 、bind
-
三者第一个参数都是this要指向的对象,也就是想指定的上下文;
-
apply 、 call 、bind 三者都可以利用后续参数传参;
-
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。