方法一:

如果用call進行系結,其實相當于在egg物件里面增加一個person函式,再用egg.person()呼叫就好了

簡單來說就是在egg這個位置開始進行呼叫,然后執行person函式,如果發現了this就會系結到egg,因為egg直接執行了person,egg是真正的呼叫位置,因此this指向了egg

此時的this指向window,person函式進行呼叫,然后執行newCall函式,發現了this,因此需要進行系結,person才是真正呼叫位置,所以this指向person函式


實作call
相當于給物件obj添加了person函式,不過要記得洗掉該方法,因為不能改寫了物件

call的第一個引數是this指向,后面的引數就是函式本身的引數,但是函式本身的引數是沒有this的,但是call的第一個引數是this,所以我們需要將所有的引數另外保存起來,并且不保留第一個this引數,使得引數回歸正常的序號,獲取函式引數使用arguments物件,我們在設定newCall的時候,內部其實執行的是不帶引數的函式,也就是說沒有使用任何一個引數,所以需要將該arguments分開來顯示



但是此時egg改為null會出錯,物件不存在時候就指向window
因為可能函式person里面有回傳一個物件的問題

實作apply
第一個引數this,第二個引數為陣列,所以要么有第二個引數,要么沒有

實作bind
- bind會回傳一個函式
- 因為函式中有回傳的函式,所以在執行中容易造成this丟失,所以提前保存this,回傳的函式里面就是執行和call和apply的功能了(保存當前呼叫的函式)
- 考慮后面的引數問題,我們需要切割,但是要注意arguments其實是物件,不是陣列,因此不能直接使用陣列的切割方法,需要利用call方法把slice切割方法賦給arguments物件,這個時候就可以切割第一個陣列元素,并且賦值給arr,接下來就要將陣列放入return的函式里面,但是call接收陣列引數很麻煩,所以改為apply


- 實際bind具有柯里化特性,現在為回傳函式中傳入一個引數,結果顯示undefind,因為沒有向return的函式進行引數的傳入

- newBind里面的引數有兩個不同的arguments

- 將兩個arguments物件的陣列進行合并,所以將arguments物件轉為陣列

- 使用new,發現列印為undefind,因為這個實體和現在的原型物件沒有關系

- 將回傳函式設定為具名函式,因為有了名字的函式,才能進行關系的確認,
如果使用new來呼叫函式,也就是發生了建構式,那么實體(新物件)會系結到函式呼叫的this
new的程序


方法二:
實作call
- 將addAge函式添加到obj物件中,設為其屬性(方法)
- 然后在作用域是obj的情況下,執行addAge方法
- 最后洗掉obj里面的addAge函式,這樣就不會影響obj物件
- this指向addAge函式,原因:Function是所有function函式的建構式,然后構造器里面的this永遠指向其構造的實體,而addAge函式就是Function構造的實體


- newCall中實作引數傳入和回傳值(像原來的addAge一樣可以回傳值)這兩個特性
- 將args轉換為字串,這樣eval()中就傳入的是全字串格式
- 但是此時第一個引數改為null會出錯,物件不存在時候就指向window

實作apply

實作bind
原理:將addStuff函式添加到obj物件的作用域下,當執行該addStuf函式時,其中的this將指向obj,且將26傳入age中,所以age就變為了私有引數的元素,在后面使用addStuffToObj的程序中,無法更改age的輸入值,只能傳入birth

- 忽略第一個引數,從第二個引數開始獲得

- 生成新的函式binded,在binded中運行func(即是addStuff),并且是在指定的作用域obj下運行,然后傳入引數,該引數包括age和birth,所以要連接在一起


- 使用new時,bind的第一引數不再是傳入obj作用域了,因為建構式的作用域會在new作用下,被賦值到新生成的實體上,所以可以不傳值,或者(null,引數)


- 為實作原生的new效果,所以在binded中加入判斷陳述句,如果在呼叫binded中,使用new來呼叫的,此處的this是指向,new生成的實體物件stuff,而運行傳入的func(即是addStuff)就需要在stuff的作用域下運行,所以age和birth賦值到stuff物件的屬性里面

- 而其他情況,像這樣,bind2生成的不是建構式,而是普通函式


- 如果處在原型鏈上,生成的新的建構式newAddStuff應該繼承舊的addStuff建構式的原型,但是截至目前還未完成該操作 ,此處的this指向addStuff函式,是的addStuff的原型賦值到了新的建構式newAddStuff(binded.prototype)的原型,所以newAddStuff上的原型鏈繼承了addStuff

- 更改newAddStuff的prototype時將會更改addStuff的prototype,這是不正確的,解決方案,建立一個空函式,使得空函式的prototype等于addStuff的prototype,讓新生成的binded函式的原型成為空函式的實體,則在更改新生成的實體binded的prototype的程序中,只會更改新的實體

內部功能,而不會觸及到addStuff的原型鏈了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/287745.html
標籤:其他
上一篇:Vue考前詳細總結
下一篇:深拷貝和原型原型鏈(面事題)
