本文已参与[新人创作礼]活动,一起开启掘金创作之路。
每个函数都包含两个非继承而来的方法:call()和apply()
相同点:作用一样,call与apply都是设置函数中this的指向问题,以扩充函数赖以运行的作用域。
在对象调用方式时,一般来说此时this指向的是该方法所在的对象。但是使用call()和apply()后,this的指向就改变了。
不同点:两者的传参方式不同,call可以将该方法的参数分别作为自己的多个参数,如:obj1.method.call(obj,"参数1","参数2"),apply则是需要将该方法的参数合并成一个数组作为自己的一个参数,如obj1.method.apply(obj,["参数1","参数2"]),method就收到了参数1和参数2。
1.无参数时
无参数时,通过call()和apply()来指向this时,是将this的指向改为window。
/*
无参数实现
*/
var school = "A大学";
var master = "通信";
var person = {
school: "B大学",
master:"计算机",
getDegree(){
console.log("我在"+this.school+"取得了学士学位,我的专业为"+this.master);
},
getMajorCourse(course1,course2){
console.log("我的主修课程有:"+course1+","+course2);
}
}
// 如果直接调用call和apply,则this指向window。
person.getDegree.call();
person.getDegree.apply();
此时,输出是:
2.有参数时
/*
有参数实现,this指向student
*/
var school = "A大学";
var master = "通信";
var person = {
school: "B大学",
master:"计算机",
getDegree(){
console.log("我在"+this.school+"取得了学士学位,我的专业为"+this.master);
},
getMajorCourse(course1,course2){
console.log("我的主修课程有:"+course1+","+course2);
}
}
var student = {
school:"C大学",
master:"车联网",
}
person.getDegree.call(student);
person.getDegree.apply(student);
console.log("--------方法分割线--------");
person.getMajorCourse.call(student,"课程1","课程2");
person.getMajorCourse.apply(student,["课程1","课程2"]);
此时,输出是:
3.call(this,arguments)
/*
call(this,arguments);
this:指向当前所在的this指向
argument:参数
*/
var school = "A大学";
var master = "通信";
var person = {
school: "B大学",
master:"计算机",
getDegree(){
console.log("我在"+this.school+"取得了学士学位,我的专业为"+this.master);
},
getMajorCourse(course1,course2){
console.log("我的主修课程有:"+course1+","+course2);
}
}
var student = {
school:"C大学",
master:"车联网",
getDegree(){
console.log(arguments); // ["课程111111111111", "课程22222222222",...]
person.getDegree.call(student,arguments); // 我在C大学取得了学士学位,我的专业为车联网
person.getDegree.call(this,arguments); // 我在C大学取得了学士学位,我的专业为车联网
/*
由于person.getDegree使用call改变this的指向,并在student对象中使用,此时this本身就指向student对象。
所以,可写成person.getDegree.call(student,arguments);
因此call(this,arguments)可以方便的应用于不同对象的方法,不需要每次修改对象。
*/
person.getMajorCourse.call(this,arguments[0],arguments[1]); //我的主修课程有:课程111111111111,课程22222222222
}
}
// 调用student对象的方法
student.getDegree("课程111111111111","课程22222222222");
此时,输出是:
4.apply(this,arguments)
/*
apply(this,arguments);
this:指向当前所在的this指向
argument:参数
*/
var school = "A大学";
var master = "通信";
var person = {
school: "B大学",
master:"计算机",
getDegree(){
console.log("我在"+this.school+"取得了学士学位,我的专业为"+this.master);
},
getMajorCourse(course1,course2){
console.log("我的主修课程有:"+course1+","+course2);
}
}
var student = {
school:"C大学",
master:"车联网",
getDegree(){
console.log(arguments); // ["课程111111111111", "课程22222222222",...]
person.getDegree.apply(student,arguments); // 我在C大学取得了学士学位,我的专业为车联网
person.getDegree.apply(this,arguments); // 我在C大学取得了学士学位,我的专业为车联网
/*
由于person.getDegree使用apply改变this的指向,并在student对象中使用,此时this本身就指向student对象。
所以,可写成person.getDegree.apply(student,arguments);
因此apply(this,arguments)可以方便的应用于不同对象的方法,不需要每次修改对象。
*/
person.getMajorCourse.apply(this,arguments); //我的主修课程有:课程111111111111,课程22222222222
}
}
// 调用student对象的方法
student.getDegree("课程111111111111","课程22222222222");
此时,输出是: