美文网首页
JavaScript ,call和apply 模拟实现,原生实现

JavaScript ,call和apply 模拟实现,原生实现

作者: aaagu1234 | 来源:发表于2020-04-30 13:51 被阅读0次

    call 是改变了 this 的指向的。

    this的意思是谁调用指向谁 理解一下这句话。

    var foo =  {
        value: 1,
        bar: function() {
            console.log(this.value)
        }
    };
    //   foo这个对象调用了bar函数,
    //  那么bar函数里面的this指向的是foo对象
    foo.bar(); 
    

    直接上最终代码:

     
    Function.prototype.mycall = function(context) {
       var context = context || window;
        context.fn = this;  // this 指的就是 foo函数
        var args = [];
        for(var i = 1,len=arguments.length; i < len; i++){
          args.push('arguments[' + i +']');  // foo.call(obj , 'john', 'M') 第一个参数不需要加入,循环从1开始。
        }
        var result = eval('context.fn('+ args +')' )// 利用eval来执行,因为参数是动态的。
        delete context.fn;
        return result
    }
    
    // 使用方法:
    function  foo(sex,age){
      console.log(this.name);  // obj 的name
      this.sex = sex;
      this.age = age;
      console.log(sex,age);
    }
    var obj = {name: 'mike'};
    foo.mycall(obj,'M',18);
    

    apply 模拟实现
    和call的区别就是参数是数组形式。

    Function.prototype.apply = function (context, arr) {
        var context = Object(context) || window;
        context.fn = this;
    
        var result;
        if (!arr) {
            result = context.fn();
        }
        else {
            var args = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                args.push('arr[' + i + ']');
            }
            result = eval('context.fn(' + args + ')')
        }
    
        delete context.fn
        return result;
    }
    

    bind 模拟:

    Function.prototype.bind2 = function (context) {
    
        if (typeof this !== "function") {
          throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
        }
    
        var self = this;
        var args = Array.prototype.slice.call(arguments, 1);
        var fNOP = function () {};
    
        var fbound = function () {
            self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
        }
    
        fNOP.prototype = this.prototype;
        fbound.prototype = new fNOP();
    
        return fbound;
    
    }
     
    

    参考: https://juejin.im/post/5907eb99570c3500582ca23c
    https://juejin.im/post/59093b1fa0bb9f006517b906

    相关文章

      网友评论

          本文标题:JavaScript ,call和apply 模拟实现,原生实现

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