Web開發學習筆記07 — bind、call、apply


Posted by Teagan Hsu on 2020-12-08

簡單來說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次方)

參考資料:

  1. [筆記] 了解function borrowing和function currying ─ bind(), call(), apply() 的應用
  2. JavaScript - call,apply,bind
  3. 一次搞懂前端面試最愛問的 apply、bind、call
  4. Function.prototype.bind()
  5. Function.prototype.call()
  6. Function.prototype.apply()

#bind #call #apply #this







Related Posts

D50_W6  Chrome debug + W6 直播檢討

D50_W6 Chrome debug + W6 直播檢討

command line,那個電影世界裡駭客電腦上的黑色小視窗

command line,那個電影世界裡駭客電腦上的黑色小視窗

用 JavaScript 學習資料結構和演算法:堆疊(Stack)篇

用 JavaScript 學習資料結構和演算法:堆疊(Stack)篇


Comments