js深刻學習之call,apply,bind函數的實現

1. call函數的實現

做用:函數調用,經常使用來給函數綁定指定的this,並執行該函數前端

參數:接收多個參數,第一個參數爲要指定的 this對象windows

  • 若是沒有傳入指定的對象,或者指定的對象爲 undefined,則默認指定 windows爲要綁定的對象
var myObj = {
 name:'我是前端bug開發攻城獅'
}

function myFunc(name,age){
 console.log('argument.name===',name)
 console.log('this.name:age==',this.name,':',age)
}

Function.prototype.myCall = function(context){
 context = context || windows;
 context.fn = this;
 var args = [...arguments].splice(1,arguments.length-1);
 var result = context.fn(...args)
 delete context.fn;
 return result
}

myFunc.myCall(myObj,'路人甲',100)
複製代碼

第二版數組

var myObj = {
 name:'我是前端bug開發攻城獅'
}

var name = 'global'

function myFunc(name,age){
 console.log('argument.name==',name)
 console.log('this.name:age==',this.name,':',age)
}

Function.prototype.myCall = function(context){
 if(context && typeof context !== 'object'){
     return Error('第一個參數必須爲對象')
 }
 context = context || window;
 context.fn = this;
 var args = [...arguments].splice(1,arguments.length-1);
 var result = context.fn(...args)
 delete context.fn;
 return result
}

// muFunc.myCall(myObj,'路人甲',100)
myFunc.myCall(123);

複製代碼

2. apply函數的實現

用法:同 call函數,惟一的區別就是,apply接收兩個參數app

  1. 要綁定的this對象
  2. 參數數組
var myObj = {
 name:'我是前端bug開發攻城獅'
}

var name = 'global name';

function myFunc(name,age){
 return {
     name: this.name,
     age:age,
     argName:name,
 }
}

Function.prototype.myBind = function(context,argArray){
 if(context && typeof context !== 'object'){
     return Error('第一個參數必須爲對象')
 }
 context = context || window;
 context.fn = this;
 var result;
 if(argArray){
     result = context.fn(...argArray)
 }else{
     result = context.fn()
 }
 delete context.fn;
 return result
}

myFunc.myBind(myObj,['Kobe',24]);
複製代碼

3. bind函數的實現

用法:用來給調用的函數綁定一個this對象,並返回這個綁定了this以後的函數(只返回函數的引用,並不執行哦)函數

參數:接收多個參數,第一個參數爲要綁定爲this的對象,剩下的爲函數的形參ui

注意:this

  1. bind方法返回的函數,還能夠繼續收參數
  2. bind方法返回的函數,能夠經過 new實例化
    • 經過 new 實例化以後,以前綁定的this會失效
function myFunction(name,age){
    console.log(this.value,name,age)
    return {
        value:this.value,
        name:name,
        age:age
    }
}


Function.prototype.myBind = function(context){

    if(context && typeof context !== 'object'){
        return Error('第一個參數必須爲對象')
    }

    if(typeof this !== 'function'){
        return Error('只有函數才能調用myBind函數')
    }
    contex = context || window;
    var args = [...arguments].slice(1)
    var that = this;
   
    var fn = function(){
        that.call(this instanceof fn ? this : context,...args,...arguments)
    }
    return fn;
}

var fn1 = myFunction.myBind({value:'James'},'Kobe');
var result = new fn1('24')
console.log(result)
複製代碼

4. 總結

相同點:call,apply,bind函數都是用來爲函數綁定指定的 this對象的,且三個函數的第一個參數都必須爲要綁定的this對象,沒傳則默認爲 window,傳的不是對象則報錯spa

不一樣點:prototype

  • call:call函數從第二個參數開始,接收的參數都做爲函數的形參,能夠有多個
  • apply:apply與call惟一的區別就是,apply接收的第二個參數是一個數組,全部函數的形參都包含在數組裏面
  • bind:bind函數不一樣於前兩個函數,bind函數返回一個綁定 this 以後的函數的引用。而不是直接調用。且調用返回的函數的時候,能夠繼續傳參,做爲函數的形參使用(後續傳入的參數會對應函數的形參列表,依次對應)。最特別的一點是,bind函數返回的函數的引用,能夠經過 new 實例化,實例化以後的函數就失去了bind綁定的this。
相關文章
相關標籤/搜索