JavaScript 中的 bind()、apply() 和 call()鮮為人知的區別
每個開發人員都應該充分了解它們的工作原理,并能夠辨別它們之間的細微差別。
所以你知道,JS 函數是一等公民。
這意味著:它們都只是對象值——Function 類的所有實例,具有方法和屬性:
因此 bind()、apply() 和 call() 是每個 JavaScript 函數都具有的 3 個基本方法。
bind()
你是否和我一起經歷過 React 早期的痛苦歲月;那時我們還在使用這樣的類組件和事件處理程序?
這只是 bind() 的多種應用之一——一種被嚴重低估的 JavaScript 方法。
如果沒有 bind(),sayName() 會一團糟——alert() 永遠無法工作。
因為 React 內部對這個方法做了一些可疑的事情,完全搞砸了 this 內部的含義。
之前 sayName 完全可以毫無問題地顯示警報——就像在這個其他類中一樣:
但猜猜 React 在幕后對greet事件處理程序方法做了什么?
它將其重新分配給另一個變量:
猜猜會發生什么——它無處可尋:
這就是 bind 發揮作用的地方——它將 this 更改為您選擇的任何實例對象:
因此,我們將函數綁定到對象——綁定目標。
(我知道它是“綁定的”,但我們可以說它是綁定的,就像我們將“index”而不是“indices”說成“indexes”一樣)。
它是不可變的——它返回綁定函數而不改變原始函數的任何內容。
這讓我們可以盡可能多地使用它:
vs call()
call 和 bind 之間只有很小的區別。
bind 創建綁定函數供您隨意使用。
但是 call?它會動態創建一個臨時綁定函數并立即調用它:
因此, call() 基本上就是 bind() + 一個調用。
但是當函數有參數時怎么辦呢?我們該怎么辦?
完全沒問題 — 只需將它們作為更多參數傳遞給call即可:
你實際上可以使用 bind() 做同樣的事情:
vs apply()
一開始你可能會認為 apply() 和 call() 做的事情完全一樣:
但就像 bind() 與 call() 一樣,需要注意一個細微的差別:
傳遞的參數:
我使用一個助記技巧來記住兩者的區別:
- call() 用于逗號
- apply() 用于數組
回顧總結
- bind()——綁定到此并返回一個新函數,可重復使用。
- call()——綁定 + 調用函數,使用逗號傳遞參數。
- apply()——綁定 + 調用函數,使用數組傳遞參數。