美文网首页
手写bind函数

手写bind函数

作者: 小旎子_8327 | 来源:发表于2019-06-25 17:02 被阅读0次

    参考MDN

    task1:判断Function.prototype.bind是否存在, 如果存在,不重写,不存在,需要重写

       if(!Function.prototype.bind){
            Function.prototype.bind = function(obj){}
       }
    

    task2: 调用到时候,例如func.bind(),需要判断func 是不是个函数,如果不是,报错。注意,bind方法的this是隐式绑定,指向func.

       if(typeof this !== 'function'){
            throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
       }
    

    task3: 参数分割,调用方式func.bind(obj, arg1)(arg2) 等价于func.bind(obj)(arg1,arg2)

         //参数一
         var args1 = Array.prototype.slice.call(arguments,1);
    
          //参数二
          var args2 = Array.prototype.slice.call(arguments);
          var args = args1.concat(args2)
    

    task4: 有两种bind的用法,一种是func.bind(obj)(arg), 一种是 new func.bind(obj)(arg),其中,后者的obj参数默认作废,等同于new func(arg),这是由于new的绑定优先级高于bind的缘故。所以,执行的时候需要判断是不是new方式执行

    Function.prototype.bind = function(obj){
       ...
           //第二种方式 new 的时候,第一步会创建一个空的对象,该对象的_proto_指向构造函数的prototype, 因此该对象.instanceof(构造函数)===true
           //第二步会将this指向这个空对象,并执行以下构造函数func内容。
           //在构造函数里可以用this.instanceof(fBound)判断是否是new方式执行,如果不是,说明是第一种方式执行,this指向参数obj
       var fBound= function(){
           var _this = this.instanceof(fBound) ? this : obj;
       }
    }
    

    task5: 维护原型关系
    new的时候,新对象的_proto_指向构造函数的prototype。期望新对象的原型链向上查找能够找到func.prototype

       var fNOP = function(){}
       if(this.prototype){ 
             fNOP.prototype=this.prototype
       }
      fBound.prototype = new fNOP()
    // 新对象._proto_ = fBound.prototype
    //fBound.prototype._proto_=fNOP.prototype=this.prototype
    

    代码

    if(!Function.prototype.bind){
        Function.prototype.bind = function (obj) {
             if(typeof this !== 'function'){
                  throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
             }
             var args1 = Array.prototype.slice.call(arguments,1);
             var fToBind = this;
             var fBound = function(){
                 var args2 = Array.prototype.slice.call(arguments);
                 var args = args1.concat(args2);
                 var _this_ = this.instanceof(fBound)? this : obj;
                 fToBind.apply(_this_, args);
             }
             var fNOP = function(){};
            if(this.prototype){
                 fNOP.prototype = this.prototype;
            }
            fBound.prototype = new fNOP():
        }
        return fBound;
    }
    

    相关文章

      网友评论

          本文标题:手写bind函数

          本文链接:https://www.haomeiwen.com/subject/rixxcctx.html