您的位置:首页 > 移动开发

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

2016-02-17 09:39 239 查看
在开发过程中,特别是复杂控件封装时,常会用到动态调用函数。那么动态调用函数实则就是利用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 方法的使用 和 对象是引用类型 这两个关键点可以很轻松明白为什么第二次输出是=>>。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息