叙述
call()、bind()、apply()都是js预定义的方法,可以挂载对象或某个属性,来改变函数内部的this
指向,他们最大的区别就是传入参数的方式不太一样。
call()
改变fn函数的this指向为obj对象。
let obj = {
name: "小明",
age: 13
}
function fn() {
console.log(this);
}
fn.call(obj);
/*
* call()参数:
* 1. 重定义this指向为某个对象或属性。
* 2. 传入的实参,可以传入多个,逗号隔开。例如:fn.call(obj, "小黑", 18, "163cm")
*/
call()传入实参的语法:
let obj = {
name: null,
age: null,
height: null
}
function fn(name, age, height) {
this.name = name;
this.age = age;
this.height = height;
console.log(this); // 返回结果为:{name: 小明, age: 18, height: "183cm"}
}
fn.call(obj, "小明", 18, "183cm");
bind()
bind()方法绑定后会返回一会函数。
let obj = {
a: function() {
return "Hellow";
},
b: function() {
return "origin";
}
}
function person() {
console.log(this.a()); // 返回结果为:Hellow
};
person.bind(obj)(); // 重定向this指向为obj对象,因为bind()绑定后会返回一个函数,在写一对小括号进行调用。
bind()传入实参的语法:
let obj = {
a: function() {
return "Hellow";
},
b: function() {
return "origin";
}
}
function person(msg) {
console.log(this.a(), msg); // 返回结果为:Hellow
};
person.bind(obj, "JavaScript")(); // 重定向this指向为obj对象
或者也可以是这样
person.bind(obj)("JavaScript");
apply()
let obj = {
a: function() {
return "Hellow";
},
b: function() {
return "origin";
}
}
function person(msg) {
console.log(this.b()); // 返回结果为:origin
};
person.apply(obj); // 重定向this指向为obj对象
apply()传入实参的语法:
apply()在传入参数时,与上了两中方法不同,apply是以数组的方式传入,数组内的每一个都对应着一个形参。
如下代码例:
let obj = {
a: function() {
return "Hellow";
},
b: function() {
return "origin";
}
}
function person(msg1, msg2, msg3) {
console.log(this.b(),msg1, msg2, msg3); // 返回结果为:origin 哈哈哈 嘻嘻嘻 呜呜呜
};
person.apply(obj, ["哈哈哈", "嘻嘻嘻", "呜呜呜"]); // 重定向this指向为obj对象
总结一下区别
相同点
call()、bind()、apply()都是重定向function
中的this
指向,并且都可以进行传递参数。
不同点
- call() 传入的参数以逗号隔开,可以是任何类型。并且在call()的同时函数会执行。
- bind() 传入的参数以逗号隔开,可以是任何类型。在bind()的同时不会执行函数,但是会返回一个函数。
- apply() 传入参数的时候必须是一个数组,数组内的每一个值都对应着一个形参,并且在apply()的同时函数会执行。