實現call方法
Function.prototype.myCall = function(thisArg, ...args) { const fn = Symbol('fn') // 聲明一個獨有的Symbol屬性, 防止fn覆蓋已有屬性 thisArg = thisArg || window // 若沒有傳入this, 默認綁定window對象 thisArg[fn] = this // this指向調用call的對象,即我們要改變this指向的函數 const result = thisArg[fn](...args) // 執行當前函數 delete thisArg[fn] // 刪除我們聲明的fn屬性 return result // 返回函數執行結果 } //測試 foo.myCall(obj)
實現一個apply,跟call相似,把參數列表改為參數數組
Function.prototype.myApply = function(thisArg, args) { const fn = Symbol('fn') // 聲明一個獨有的Symbol屬性, 防止fn覆蓋已有屬性 thisArg = thisArg || window // 若沒有傳入this, 默認綁定window對象 thisArg[fn] = this // this指向調用call的對象,即我們要改變this指向的函數 const result = thisArg[fn](...args) // 執行當前函數 delete thisArg[fn] // 刪除我們聲明的fn屬性 return result // 返回函數執行結果 } //測試 foo.myApply(obj, [])
實現bind,區別在於
Function.prototype.myBind = function (thisArg, ...args) { var self = this // new優先級 var fbound = function () { self.apply(this instanceof self ? this : thisArg, args.concat(Array.prototype.slice.call(arguments))) } // 繼承原型上的屬性和方法 fbound.prototype = Object.create(self.prototype); return fbound; } //測試 const obj = { name: '寫代碼像蔡徐抻' } function foo() { console.log(this.name) console.log(arguments) } foo.myBind(obj, 'a', 'b', 'c')()