手寫實現call,apply,bind方法

實現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')()
相關文章
相關標籤/搜索