美文网首页
js Function.prototype的隐藏方法call、a

js Function.prototype的隐藏方法call、a

作者: pretty_rain | 来源:发表于2019-06-18 18:19 被阅读0次

    1.call、apply的用法

    call、apply、bind这三个都是函数自带的方法(Function.prototype原型的方法),它是Javascript引擎内在实现的,因此每个方法都有apply和call属性,这三个方法能改变函数内部this的指向,当第一个参数是null时不改变this指向。

    call()

    这个方法的第一个参数表示this指向的对象,后面的所有参数都是函数的参数

    //所有变量都是window的属性
        var item = "abc";
        //其实是Function的实例
        function fn(){
            console.log(this.item);
        }
        fn();
        //Object的实例
        var data = {
               item:123
        }
        //改变了this的指向
        fn.call(data);
    

    apply()

    這個方法和call方法的作用都是相同的,只不过在传递参数时候,call方法可以传递多个参数,而apply方法只能传递两个参数,并且第二个要求是一个数组。

    /*apply在对象中使用*/
        function Product(){
    
        }
        Product.prototype={
            binddom:function(a,b){
                console.log(a+b);
            },
        }
        Product.prototype.binddom.apply(null,[1,2])
        var p = new Product();
        p.binddom.apply(null,[1,2]);
        /*apply在函数中的使用*/
        function fun(num1,num2,num3){
            var arr = Array.prototype.slice.call(arguments);
            console.log(arr.length);
        }
        fun.apply(null,[5,6,7]);
    

    2.call函数模拟实现

    实现第一版 函数无参数

        /*实现第一版*/
        Function.prototype.myCall = function(context){
            //给context添加属性指向this
            context.fun = this;
            //执行
            context.fun();
            //删除添加的属性
            delete context.fun;
        }
        var obj = {
            value:1
        }
        function fun(){
            console.log(this.value);
        }
        fun.myCall(obj);
    

    实现第二版 函数有参数用伪数组遍历,同时用eval执行函数

        /*实现第二版 加参数*/
        Function.prototype.myCall1 = function(context){
            //给context添加属性指向this
            context.fun = this;
            //参数数组
            var params = [];
            for(var i = 1; i < arguments.length; i++){
                params.push('arguments['+i+']');
            }
            //执行
            eval('context.fun('+params+')');
            //删除添加的属性
            delete context.fun;
        }
        var obj1 = {
            value : 2
        }
        function fun1(aa,bb){
            console.log(this.value+"参数aa"+aa +"参数bb"+bb);
        }
        fun1.myCall1(obj1,'tom',12);
    

    实现第三版 如果context为null 时把context指向window

        /*实现第三版 如果context为null 时把context指向window
        所有全局的函数和变量都是window的属性*/
    
        Function.prototype.myCall2 = function(context){
            var context = context || window;
            //给context添加属性指向this
            context.fun = this;
            //参数数组
            var params = [];
            for(var i = 1; i < arguments.length; i++){
                params.push('arguments['+i+']');
            }
            //执行
            eval('context.fun('+params+')');
            //删除添加的属性
            delete context.fun;
        }
        var obj2 = {
            value : 2
        }
        function fun2(aa,bb){
            console.log(this.value+"参数aa"+aa +"参数bb"+bb);
        }
        fun2.myCall2(obj2,'jack',9);
    

    相关文章

      网友评论

          本文标题:js Function.prototype的隐藏方法call、a

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