手把手擼出apply,call,bind的原理實現

1. apply的原理的實現

 Function.prototype.myapply = function (context) {
    context = context || window; // 當前上下文指向函數或者window
    context.fn = this; // 給當前添加屬性fn,並且該屬性爲調用的函數,那麼this就是指向當前的調用函數
      let resurlt;
      // 判斷存儲是否有第二個參數,如果有第二個參數就將其展開
      if (arguments[1]) { // 判斷apply是否有參數(第二個參數)
          resurlt = context.fn(...arguments[1])
      } else {
          resurlt = context.fn()
      }
      delete context.fn; // 刪除原型鏈上的fn屬性
      return resurlt;
  }
  let name = 'ys';
  let age = '18';
  let obj = {
      name: 'xiaoli',
      myF: function (name, age) {
          console.log(this)
          console.log(name + '---' + age)
      }
  }
  let myobj = [12, 78]
  obj.myF(1, 2) // {name: "xiaoli", myF: ƒ}  this指向obj
  obj.myF.myapply(this,myobj) // this指向window

2. call的原理的實現

Function.prototype.mycall = function(context){
   context = context || window; // 當前上下文的指向
   context.fn = this; // 給context創建一個fn屬性,並且該屬性爲調用的函數
   const args = [...arguments].slice(1);// 傳入的參數
   const resurlt = context.fn(...args); // 給調用的函數傳參
   delete context.fn; // 刪除對象上的函數
   return resurlt; // 返回調用函數
 }

3.bind的原理的實現

Function.prototype.mybind = function(context) {
   
   if(typeof this !== 'function'){ // 判斷是否是函數,不是拋出異常
     throw new TypeError('error')
   }
   var args = arguments.slice(1); // 獲取參數
   var _this = this;
   return function F() {
     if(this instanceof F){ // this 是F的實例化對象,直接返回new 一個對象
       return new _this(args,...arguments)
     }
     return _this.apply(context,args.concat(...arguments)) // 這個是this不指向指定函數,所以需要apply綁定修改this
   }
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章