敘述
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()的同時函數會執行。