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

2019-06-18  本文已影响0人  pretty_rain

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);
上一篇 下一篇

猜你喜欢

热点阅读