iT邦幫忙

2023 iThome 鐵人賽

DAY 16
1
Modern Web

那些你可能要知道的前端知識系列 第 16

【day16】bind、call 、apply 的區別

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20230919/20148303n6S1Z1eBPh.png


JavaScript中除了基本型別(String/Number/Boolean等),其他型別(Array/Object/Data)實際上都是特定物件延伸而來,這些個特定物件裡面都有自帶的原型,可以稱它為prototype
當建立一個新的物件時,它的隱藏__proto__會自動被指到ptototype,因此這個物件才能夠任意使用prototype定義好的函式、屬性 => 我們稱之為「原形鏈」。

let arr = new Array()
arr.__proto__ === Array.prototype // true

bindcallapply三者都是JavaScript Object 的方法
使用 applycall,可以直接決定並執行一個函數,並告訴它 this 應該是什麼。bind 不會馬上執行函數,而是會給一個新的函數,當這個新的函數被執行時,它會知道 this 應該是先前指定的那個值。


bind

bind 可以綁定一個函數的 this 值,使用 bind 建立一個新的函數時,無論這個新函數在哪裡被呼叫,它的 this 值都會被固定在指定的物件上。

let calculator = {
    factor: 2,
    multiply: function(number) {
        return this.factor * number;
    }
};

let double = calculator.multiply;
console.log(double(3));  // 會輸出: NaN,因為 this 現在是全域物件或 undefined

加上bind來修正 this 指向

let fix = double.bind(calculator);
console.log(fix(3));  // 正確輸出 6

範例程式碼中:
1.先從calculator中取出multiply然後賦予值到double函式
2.在全域呼叫了double函式,因此this會指向全域,而不是calculator
3.全域中找不到multiply,因此會回傳全域物件(非嚴格模式)或是 undefined(嚴格模式)
4.undefined * 3 進行運算會回傳 NAN
(加上bind修正)
5.建立一個新函數fix,將double函數的this值綁定到calculator物件上
6.fix之後在哪邊呼叫,它的this都會是固定指向calculator

bind 特點

  • 可以指定 this 值
  • 回傳一個新函數

call 、 apply

callapply放在一起講的原因是它們極為相似
最大的不同是 call 接受一連串的參數,而 apply 接受一組陣列形式的參數 --MDN

const restaurant = {
    name: "Tasty Restaurant",
    bill: function(food, drink) {
        console.log(`Bill from ${this.name}:`);
        console.log(`Food: ${food}`);
        console.log(`Drink: ${drink}`);
    }
};

const cafe = {
    name: "Cozy Cafe"
};

// 使用 call 來為 cafe 印出bill
restaurant.bill.call(cafe, "Sandwich", "Coffee");
// 輸出:
// Bill from Cozy Cafe:
// Food: Sandwich
// Drink: Coffee

// 使用 apply 來為 cafe 印出bill
restaurant.bill.apply(cafe, ["Croissant", "Latte"]);
// 輸出:
// Bill from Cozy Cafe:
// Food: Croissant
// Drink: Latte

call

restaurant.bill.call(cafe, "Sandwich", "Coffee")的作用是調用restaurantbill方法,然後將 this 值指到 cafe,所以我們只要調用restaurant方法,輸出的name名稱即會是cafe

apply

基本上applycall的執行方式是一樣的,相較於call不同的是,apply第二個參數是帶入一個Array

以apply做詳細的說明:
1.apply 方法的第一個參數設定指到 this 值的物件,在範例中,我們選擇了 cafe 作為 this 值
2.apply第二個參數帶入一個Array,這邊帶入「["Croissant", "Latte"]」做為參數,傳遞給bill函數
3.當bill的方法被執行時,他的this值是指向cafe,這樣this.name就會輸出"Cozy Cafe"

特點

call

  • 指定this
  • 單獨傳遞參數,call從第二個參數開始可以接受一連串的參數,這些參數將會被依序傳遞給函數

apply

  • 指定this
  • 第二個參數使用單一Array作為參數

圖表整理三種方法區別

https://ithelp.ithome.com.tw/upload/images/20230919/20148303Ba1QVa13sO.png


參考文章
JavaScript - call,apply,bind
Function.prototype.bind()
Function.prototype.call


上一篇
【day15】AJAX、Fetch、Axios
下一篇
【day17】JavaScript "this"
系列文
那些你可能要知道的前端知識30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言