實現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類似,把參數列表改成參數數組app
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')()