之前已經實現過了call,apply和new。今天順便把bind也實現下。
首先:
ok,上代碼~
Function.prototype.mybind = function(context){ let that = this; let args1 = Array.prototype.slice.call(arguments,1); let bindFn = function(){ let args2 = Array.prototype.slice.call(arguments); return that.apply(this instanceof bindFn?this:context,args1.concat(args2)); } let Fn = function(){}; Fn.prototype = this.prototype; bindFn.prototype = new Fn(); return bindFn; }
首先 獲取到第一次傳遞的參數args1,此處要做截取處理,因為第一個參數是this。接下來聲明一個函數bindFn,在該bindFn中獲取了第二次傳的參數args2,并且返回了that的執行。此處的that就是原函數,執行該原函數綁定原函數this的時候要注意判斷。如果this是構造函數bindFn new出來的實例,那么此處的this一定是該實例本身。反之,則是bind方法傳遞的this(context)。最后再把兩次獲得的參數通過concat()連接起來傳遞進去,這樣就實現了前3條。
最后一條:構造函數上的屬性和方法,每個實例上都有。 此處通過一個中間函數Fn,來連接原型鏈。Fn的prototype等于this的prototype。Fn和this指向同一個原型對象。bindFn的prototype又等于Fn的實例。Fn的實例的__proto__又指向Fn的prototype。即bindFn的prototype指向和this的prototype一樣,指向同一個原型對象。至此,就實現了自己的bind方法。
代碼寫好了, 測試一下吧~
Function.prototype.mybind = function(context){ let that = this; let args1 = Array.prototype.slice.call(arguments,1); let bindFn = function(){ let args2 = Array.prototype.slice.call(arguments); return that.apply(this instanceof bindFn?this:context,args1.concat(args2)); } let Fn = function(){}; Fn.prototype = this.prototype; bindFn.prototype = new Fn(); return bindFn; } let obj = { name:'tiger' } function fn(name,age){ this.say = '汪汪~'; console.log(this); console.log(this.name+'養了一只'+name+','+age+'歲了 '); } /** 第一次傳參 */ let bindFn = fn.mybind(obj,'聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com