美文网首页
call apply bind 学习及自己手写实现!

call apply bind 学习及自己手写实现!

作者: 不敢大声说话的web小萌新 | 来源:发表于2019-05-22 14:37 被阅读0次

    学习分析call , apply , bind 源码,及分析。。

    在学习call,apply,bind 这三个API时,他们对context的指向有修改。

    那么就带着一个疑问来学习这代码吧!(需要有JS 原型基础)。

    我们先实现下call 能做什么。

    function say(){
        console.log('my name is ' + this.name + ' , it is ' + this.age);
    }
    
    var me = {
        name: 'LiaoXiang',
        age: 12
    }
    say();      //my name is  , it is undefined
    say.call(me);   //my name is LiaoXiang , it is 12
    

    看上面的方法,我们来思考一下 是不是在me 这个方法中拥有say 这个方法就能实现?

    var me = {
        name: 'liaoxiang',
        age: 12,
        say(){
            console.log('my name is ' + this.name + ' , it is ' + this.age);
        }
    }
    me.say();       // my name is liaoxiang , it is 12
    

    根据上面的思想,我们是需要在上面注入一个方法这样就解决了我们想要处理的问题。

    //先实现这个
    Object.prototype.myCall = function(context){
        context = context || window ; // 没传指向window
        context.fun = this; // this 指向的是调用myCall的函数
        /**
        *这里如果不删除context.fun 那么在调用的时候永久性的放入的函数中加入了一个方法(浪费内存);
        *解决 delete context.fun
        **/
        var result = context.fun();
        delete context.fun ;
        return result;  
    }
    
    say.myCall(me);     //my name is LiaoXiang , it is 12    this指向完成!
    

    call apply 的后面的参数怎么用忘记了 想不忙着写,先实现bind方法!

    已知bind 方法直接改变一个方法的this 指向

    Function.prototype.myBind = function(context){
        if(typeof this === 'function'){     //this  调用myBind的对象
            throw new TypeError(this + 'is function');
        }
        var self = this;
        return self.myCall(context)
    }
    

    下面我们是先call和apply 的参数方法。 从上面的myCall 我们可以联想到apply 的指向方法是完全一样的,只是在参数的处理不一样,call(obj,arg1,arg2.....), apply(obj,[ ]) 第二个参数接受的一个数组。

    例如: 求一个数组中的最大值

    Math.max.apply(null, [6,4,8,3,9]);
    

    apply 和 call的用法基本完全一致,不过他们接受的参数不一样。

    Object.prototype.myCall = function(context){
        context = context || window;
        context.fn = this;
        let args = Array.from(arguments).slice(1);
        let result = context.fn(...args);
        delete context.fn;
        return result;
    }
    
    Object.prototype.myApply = function(context){
        context = context || window;
        context.fn = this;
        if(arguments[1] instanceof Array){
            throw new TypeError(arguments[1] + 'is Array');
        }else{
            let result = context.fn(arguments[1]);
            delete context.fn;
            return result;
        }
    }
    

    相关文章

      网友评论

          本文标题:call apply bind 学习及自己手写实现!

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