美文网首页
JS-手动实现bind、call方法

JS-手动实现bind、call方法

作者: 葶寳寳 | 来源:发表于2019-12-27 14:42 被阅读0次

    实现bind方法

    MDN文档指出:bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

    1.首先bind方法会返回一个新的函数。在返回的新函数中调用call或apply方法来改变this指向。

    Function.prototype.bind = function(obj) {
       let self = this;
       let args = [];
       for(let i = 0; i < arguments.length; i++){
           args[i] = arguments[i];
       }
       return function () {
            return self.call(obj, ...args.splice(1), ...arguments);
       }
    }
    

    2.当我们将bind后的函数当构造函数使用时,this绑定应该失效。

    const a = 1;
    let obj  = {
       a: 2
    }
    
    function func() {
       thia.name = 'ltt';
       console.log(this.a);
    }
    
    let f = func.bind(obj);
    let o = new f();  // 2 ,实际应该输出underfind
    

    new一个构造函数时,先会创建一个构造函数(f)的子类,然后返回对象o。当构造函数有返回值是对象或数组的时候,就会返回对象/数组;当有其他类型的返回值时,返回对象o。

    let o = create Object();
    o.__proto__ = f.prototype;
    f.call(o);
    
    return o;
    

    所以,我们接着改造我们的bind方法。关键点是什么时候我们应该让this指向失效?也就是得判断什么时候把bind绑定函数当构造函数来用。

    上边也提到了,new一个构造函数的时候,先创建一个它的子类o,然后调用call方法。call方法的执行的本质是将该构造函数f作为第一个参数o的方法,然后调用o.f(),使f函数内部的this指向o。而这里的f方法,就是bind中的返回的b方法。所以我们就可以用this来判断是否为o的实例,若是,说明bind方法被用来当构造函数使用的。

    Function.prototype.bind = function(obj) {
       let self = this;
       let args = [];
       for(let i = 0; i < arguments.length; i++){
           args[i] = arguments[i];
       }
       function b() {
            return self.call(this instanceof b ? this : obj, ...args.splice(1), ...arguments);
       }
       return b;
    }
    

    至此,bind函数就大致实现了。

    实现call方法

    Function.prototype.call = function(obj){
      obj.func = this;
      var res = obj.func(arguments);
      
      delete obj.func;
      
      return res;
    }
    

    相关文章

      网友评论

          本文标题:JS-手动实现bind、call方法

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