天天看點

call、apply、bind方法的實作

先分析下3個方法的作用

改變this的指向。

傳入參數。

call apply傳回函數結果, bind 傳回新函數

一、call方法的實作

改變this指向

首先我們知道,對象上的方法,在調用時,this是指向對象的。

call、apply、bind方法的實作

知道了這一點我們就可以實作改變this的指向

call、apply、bind方法的實作

測試

call、apply、bind方法的實作

現在,改變this的值,實作了

最簡單實作es6

call、apply、bind方法的實作

二、apply方法的實作

其實apply和call差不多,沒什麼大差別

利用已經寫好的myCall來實作

call、apply、bind方法的實作

不用myCall

call、apply、bind方法的實作
call、apply、bind方法的實作

效果沒差別

三、bind方法的實作(利用call方法實作)

首先我們可以通過給目标函數指定作用域來簡單實作bind()方法:

call、apply、bind方法的實作

考慮到

函數柯裡化

的情況,我們可以建構一個更加健壯的bind():

call、apply、bind方法的實作

這次的bind()方法可以綁定對象,也支援在綁定的時候傳參。

繼續,Javascript的函數還可以作為構造函數,那麼綁定後的函數用這種方式調用時,情況就比較微妙了,需要涉及到原型鍊的傳遞:

call、apply、bind方法的實作

這是《JavaScript Web Application》一書中對bind()的實作:通過設定一個中轉構造函數F,使綁定後的函數與調用bind()的函數處于同一原型鍊上,用new操作符調用綁定後的函數,傳回的對象也能正常使用instanceof,是以這是最嚴謹的bind()實作。

對于為了在浏覽器中能支援bind()函數,隻需要對上述函數稍微修改即可:

call、apply、bind方法的實作
call、apply、bind方法的實作

四、模拟代碼

模拟call

call、apply、bind方法的實作

模拟apply

call、apply、bind方法的實作

模拟bind

call、apply、bind方法的實作
下一篇: 防抖和節流

繼續閱讀