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
    }

复制代码
相关文章
相关标签/搜索