Javascript動手實現call,bind,apply的代碼詳解

1.檢查當前調用的是否為函數

2.如果當前沒有傳入指向的this,則賦值為window

3.將fn指向當前調用的函數

4.獲取傳入的參數

5.將參數傳入fn進行調用

6.將對象上的fn刪除

7.返回結果

  //普通call的實現
  function hello(){
      console.log('hello 我是'+this.name);
  };
  let person = {
      name:'krys'
  };
  var name = 'liang';//隻有var的變量屬於window
  hello();// 'hello 我是liang'
  hello.call(person);//'hello 我是krys'
  hello.call();//'hello 我是liang'
  let person2 = {
      name:'lwl'
  }
  Function.prototype.mycall = function(context){
      //不傳入參數的時候,默認為window
      if(typeof this !== "function"){
          throw new TypeError('Error');
      }
      context = context || window;
      context.fn = this;//fn就是上面的hello方法
      const args = [...arguments].slice(1);//第一個參數不要
      const result = context.fn(...args);//把剩下的其他參數傳給hello
      delete context.fn;
      return result;
  }
  hello.mycall(person2);
function getParams(){
        console.log('我是',this.name,'獲取一些參數',...arguments);
    }
    let person3 = {
        name:'hhh'
    };
    getParams.apply(person3,['hello','world'])
    Function.prototype.myApply = function(context){
        if(typeof this !== "function"){
            throw new TypeError()
        }
        context = context || window;
        context.fn = this;
        let result;
        if(arguments[1]){
            //如果有傳入參數數組
            console.log(arguments[1])
            result  = context.fn(...arguments[1]);
        }else{
            result  = context.fn();
        }
        delete context.fn;
        return result;
    }
    getParams.myApply({name:'llll'},['jjj','kkkk','llll']);
function getParams(){
        console.log('我是',this.name,'獲取一些參數',...arguments);
    }
    let person3 = {
        name:'hhh'
    };
    let person4 = {
        name:'tttt'
    };
    getParams.bind(person3,'hello','world')
    getParams.bind(person4,'hello','world')('jjj','kkk');
    Function.prototype.myBind = function(context){
        if(typeof this !== "function"){
            throw new TypeError()
        }
        context = context || window;
        const _that = this;
        const args = [...arguments].slice(1);
        return function F(){
            if(this instanceof F){
                return new _that(...args,...arguments);//這裡的arguments是上面的jjj kkk
            }
            return _that.apply(context,args.concat(...arguments));//這裡的arguments是上面的jjj kkk
        }
    }
    getParams.myBind({name:'llll'},'jjj','kkkk','llll')('hhhhllll');

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!  

推薦閱讀: