JavaScript之實現bind

用法 :

let obj={
        name:'我'
    }
    function fn(country,type){
        console.log(this.name+'是'+country+type);
    }
    let newFn=fn.bind(obj,'中國');
    newFn('人');

複製代碼

打印結果:我是中國人.bash

咱們能夠得出結論:app

  • bind也能夠改變this,可是他不會當即執行,而是返回一個函數(高階函數),咱們須要再次執行這個綁定後的函數才能拿到結果;
  • 咱們在綁定this的時候,還能夠傳遞參數,第一個參數是this指向,從第一個參數以後的參數就是對應函數的形參,執行返回的函數也能夠傳遞參數。

先來實現第1個特色---改變this指向,並返回一個函數:

Function.prototype.mybind=function(context){
        let fn=this;//先保存須要執行的函數
        return function(){
            fn.apply(context);//讓原函數執行並經過apply改變this指向
        }
    }

複製代碼

再來實現第2個特色---能夠分次傳入參數:

Function.prototype.mybind=function(context){
        let fn=this;//先保存須要執行的函數
        let binArgs=[].slice.call(arguments,1);//獲取綁定this指向時的參數
        return function(){
            let reargs=[].slice.call(arguments);//獲取調用綁定this後函數的參數
            fn.apply(context,binArgs.concat(reargs));//讓原函數執行並經過apply改變this指向,合併兩次傳遞的參數
        }
    }
複製代碼

另外,bind還有一個特色:調用完bind後返回的函數,還能夠把這個函數當成一個類來調用. 用法:函數

let obj={
        name:'我'
    }
    function fn(country,type){
        this.name='你'
    }
    fn.prototype.city='北京'
    let newFn=fn.bind(obj)
    let oBind= new newFn();
    console.log(oBind);
    console.log(oBind.city);
複製代碼

結果打印出: fn {name: "你"} 北京 咱們能夠得出結論:ui

  • 被new以後bind函數的this並無改變,且返回的實例會繼承構造函數的構造器屬性與原型屬性

最後實現第3個特色---看成構造函數new以後,不改變this指向,並讓返回的函數原型指向構造函數的原型

增長判斷this

if(this instanceof fBound){      
     fn.apply(this,binArgs.concat(args));   
 }else{        
     fn.apply(context,binArgs.concat(args));   
 }
複製代碼

並讓返回的函數原型指向構造函數的原型spa

fBound.prototype=this.prototype;
複製代碼

代碼整合後:prototype

Function.prototype.mybind=function(context){
        let fn=this;
        let binArgs=[].slice.call(arguments,1)
         function fBound(){
            let reargs=[].slice.call(arguments)
            if(this instanceof fBound){
                fn.apply(this,binArgs.concat(reargs));
            }else{
                fn.apply(context,binArgs.concat(reargs));
            }
        }
        fBound.prototype=this.prototype
        return fBound
    }

複製代碼
相關文章
相關標籤/搜索