动态调用函数:再解apply和call

来源:互联网 发布:电梯事故数据 编辑:程序博客网 时间:2024/06/14 02:29

在开发过程中,特别是复杂控件封装时,常会用到动态调用函数。那么动态调用函数实则就是利用call和apply方法来实现的。

call和apply的区别

其实call和apply基本没有什么太大的区别,只是传递给函数的参数方式不同罢了。apply是以数组的形式进行的参数传递,而call方法可以同时传递多个参数。利用apply以数组的形式进行参数传递的特性,在很多时候能够使我们的程序更优美。比如下面的代码:

    function max() {        var m = Number.NEGATIVE_INFINITY;        for (var i = 0, l = arguments.length; i < l; i++) {            if (arguments[i] > m) m = arguments[i];        }        return m;    }    var a = [1, 33, 32, 12, 45, 30, 11, 2];    var aMaxValue = max.apply(Object, a);    alert("数组中最大数值为:"+aMaxValue);
当然如果是获取最大值,利用apply的特性,还有个更简单的方式:

    var value = Math.max.apply(Object,a);    alert("数组中最大数值为:"+aMaxValue);
直接利用Math对象的max方法。由于该方法能够接收多个参数,但是不能接收数组,而我们又不想遍历数组。那么用apply是最佳的选择了。

改变对象内部指针

call和apply主要能力就是可以改变对象内部指针。说白点就是,可以通过指定的对象来调用方法,从而完成方法中this对象的改变(变成指定的对象)。看看下面的列子,就充分的说明了call和apply的这一强大功能。

    var x = "全局";    function aFun(){        this.x = "a方法";    }    function bFun(){        this.x = "b方法";    }    function cFun(){    }    function doFun(){        alert(this.x);    }    doFun(); //全局    doFun.call(window);// 由于传入的是window,因此doFun中的this指向的就是window,那么this.x此时等价于window.x  ,因此输出“全局”    doFun.call(new aFun());//由于传入的是aFun对象,因此doFun中的this指向的就是aFun,那么this.x此时等价于aFun.x,因此输出“a方法”    doFun.call(new bFun());//由于传入的是bFun对象,因此doFun中的this指向的bFun,那么this.x此时等价于bFun.x,因此输出“b方法”    doFun.call(new cFun());//由于传入的是cFun对象,因此doFun中的this指向的就是cFun,那么this.x此时等价于cFun.x,因此输出“undefined”

利用call和apply完成继承

在js里面其实也是可以玩对象继承的。我们可以利用call和apply能够改变对象内部指针的能力,来实现继承。

    //车类    function Car (){        this.footBrake = 1;        this.getFootBrakeCount = function(){            alert("车子"+this.footBrake+"个脚刹");        }    }    //教练车    function CoachCar(){        Car.call(this);        this.footBrake = 2;    }        var p = new Car();    p.getFootBrakeCount(); //车子有1个脚刹    var d = new CoachCar();    d.getFootBrakeCount();//车子有2个脚刹
动态改变函数

 function r(x){        return (x);    }    function f(x){        x[0] = x[0]+">";        return x;    }    function o(){        var temp = r;        r = function(){            return temp.apply(this,f(arguments));        }    }function a(){    o();    alert(r("="))}    for(var i= 0;i<2;i++){        a();    }
//第一次输出:=>
//第二次输出:=>>
这段代码的关键就是在于r方法在不断的变化。for循环中a()执行两次,其实r()方法执行了三次。原因就在于r()在不停的变化。通过apply 方法的使用 和 对象是引用类型 这两个关键点可以很轻松明白为什么第二次输出是=>>。

0 0