簡單來說bind、call、apply是函式的方法(method),可以改變函式中this的指向。
基本語法
bind
fun.bind(thisArg[, arg1[, arg2[, ...]]])
call
fun.call(thisArg[, arg1[, arg2[, ...]]])
apply
fun.apply(thisArg, [argsArray])
範例1
範例中,我們想將函式logInUserName
中的this指向函式getYourFullName
。如果像範例中一樣直接寫console.log(this.getYourFullName())
,將會跑出is not a function
,因為函式logInUserName
它讀不到函式getYourFullName
。
let fullName = {
firstName: 'Hsu',
lastName: 'Teagan',
getYourFullName: function() {
let yourFullName = (`${this.firstName} ${this.lastName}`);
return yourFullName;
}
};
let logInUserName = function(password1, password2) {
console.log(this.getYourFullName());
}
logInUserName();
//Uncaught TypeError: this.getYourFullName is not a function
at logInUserName
解決辦法:我們可以使用bind、call、apply來指定this的方向。
bind:
let logInUserName = function(password1, password2) {
console.log(this.getYourFullName());
}.bind(fullName);
//或是把logInUserName.bind(fullName)存成變數,再執行。
let logInUserName = function(password1, password2) {
console.log(this.getYourFullName());
};
let newFunc = logInUserName.bind(fullName);
//執行
logInUserName();
newFunc();
//Hsu Teagan
//Hsu Teagan
call:
let logInUserName = function(password1, password2) {
console.log(this.getYourFullName());
};
//執行
logInUserName.call(fullName);
//Hsu Teagan
apply:
let logInUserName = function(password1, password2) {
console.log(this.getYourFullName());
};
//執行
logInUserName.apply(fullName);
//Hsu Teagan
範例2
除了this的用法,bind也可以傳參數進去函式中,以下程式作為示範:
function mul(a, b) {
return a * b;
};
let mulByFourTimes = mul.bind(this, 4);
mulByFourTimes(2);
//8
//(this指定了a的位置為4,所以等於4 * 2 = 8)
範例3
apply與call一樣可以帶入參數,最大差別在於apply在參數中是放入陣列。
function mul(a, b) {
return a * b;
};
mul.call(this, 1, 2);
mul.apply(this, [1, 2]);
//2
//2
bind、call、apply的差異
這樣看起來bind、call、apply的差別並不大,但還是有所差別。它們的差別在於:
1.bind為複製原本的函式,再將自己指向的this帶入函式中,所以最後要加()
來執行函式。
2.bind可以預先將參數帶入函式,所以當我們想要事先存入部分參數時,就很適合用bind。
3.call、apply是直接將this帶入函式中,所以不用加()
來執行函式。
4.apply帶入的參數要是陣列。
小測驗
以下範例中,要如和用bind、call、apply帶入參數進去呢?
function pow(a,b){
return a**b;};
解答
let power = pow.bind(this, 2);
power(3);
pow.call(this, 2, 3);
pow.apply(this, [2, 3]);
//8
//8
//8(2的3次方)
參考資料: