JS编程建议——58:灵活使用Arguments

建议58:灵活使用Arguments
JavaScript函数的参数是不固定的,调用函数时传递给它的实参也很随意,为了有效管理参数,JavaScript支持Arguments机制。
Arguments是一个伪数组,可以通过数组下标的形式获取该集合中传递给函数的参数值。例如,在下面这个函数中,没有指定形参,但在函数体内通过Arguments对象可以获取传递给该函数的每个实参值。
function f(){

for(var i = 0; i < arguments.length; i ++ ){
    alert(arguments[i]);
}

}
f(3, 3, 6);
Arguments对象仅能够在函数体内使用,它仅作为函数体的一个私有成员而存在,因此可以通过点号运算符来指定Arguments对象所属的函数。由于Arguments对象在函数体内是唯一的和可指向的,因此一般会省略前置路径,直接引用Arguments对象的调用标识符arguments。
通过数组的形式来引用Arguments对象包含的实参值,如arguments[i],其中arguments表示对Arguments对象的实际引用,变量i是Arguments对象集合的下标值,从0开始,直到arguments.length(其中length是Arguments对象的一个属性,表示Arguments对象包含的实参的个数)。
由于Arguments不是Array的实例,因此不能够直接调用数组的方法,但通过call或apply方法能够间接实现调用数组的部分方法。
Arguments对象中的每个元素实际上就是一个变量,这些变量用来存储调用函数时传递的实参值。通过arguments[]数组和已经命名的形参可以引用这些变量的值。使用Arguments对象可以随时改变实参的值。例如,在下面这个示例中把循环变量的值传递给Arguments对象元素,以实现动态改变实参的值。
function f(){

for(var i = 0; i < arguments.length; i ++ ){
    arguments[i] =i;
    alert(arguments[i]);

}
}
f(3, 3, 6); //提示1、2、3,而不是3、3、6
通过修改Arguments对象的length属性值,可以达到改变函数实参个数的目的。当length属性值增大时,增加的实参值为undefined,当length属性值减小时,则会丢弃arguments数据集合后面对应个数的元素。
Arguments在实际开发中具有重要的价值,使用它可以监测用户在调用函数时所传递的参数是否符合要求,增强函数的容错能力,同时还可以开发出很多功能强大的函数。
如果要定义的函数参数个数不确定,或者参数个数很多,又不想为每个参数都定义一个变量,此时定义函数可以保留参数列表为空,在函数内部使用Arguments对象来访问调用函数时传递的所有参数。下面这个示例就是利用Arguments对象来计算函数任意多个参数的平均值。
function avg(){

var num = 0, l = 0;
for(var i = 0; i < arguments.length; i ++ ){
    if(typeof arguments[i] != "number")
        continue;
    num += arguments[i];
    l ++ ;
}
num /= l;
return num;

}
alert(avg(1, 2, 3, 4)); //2.5
alert(avg(1, 2, "3", 4)); //2.3333333333333335
表单验证是页面设计中经常要完成的任务,下面的示例验证所输入的值是否符合邮箱地址格式。
function isEmail(){

if(arguments.length>1) throw new Error("只能够传递一个参数");
var regexp = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+

((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/;

if (arguments[0].search(regexp)!= -1)
    return true;
else
    return false;

}
var email = "abc@163.com";
alert(isEmail(email)); //true
Arguments对象包含一个callee属性,它能够返回当前Arguments对象所属的函数引用,这相当于在函数体内调用函数自身。在匿名函数中,callee属性比较有用,通过它在函数内部引用函数自身。
在下面这个示例中,通过arguments.callee获取对当前匿名函数的引用,然后通过函数的length属性确定它的形参个数。最后,通过实参和形参数目的比较来确定传递的参数是否合法。
function f(x, y, z){

var a = arguments.length;
var b = arguments.callee.length;
if (a != b){
    throw new Error("传递的参数不匹配");
}
else{
    return x + y + z;
}

}
alert(f(3, 4, 5)); //值为12
Function对象的length属性返回的是函数的形参个数,而Arguments对象的length属性返回的是函数的实参个数。如果函数不是匿名函数,则arguments.callee等价于函数名。

时间: 2024-08-30 13:49:12

JS编程建议——58:灵活使用Arguments的相关文章

JS编程建议——56:使用arguments模拟重载

建议56:使用arguments模拟重载在JavaScript中,每个函数内部可以使用arguments对象,该对象包含了函数被调用时的实际参数值.arguments对象虽然在功能上与数组有些类似,但它不是数组. arguments 对象与数组的类似体现在它有一个 length 属性,同时实际参数的值可以通过[]操作符来获取,但arguments对象并没有数组可以使用的push.pop.splice等方法.其原因是arguments对象的prototype指向的是Object.prototype

JS编程建议——59:推荐动态调用函数

建议59:推荐动态调用函数调用函数更便捷的方式是使用Function对象的call和apply方法.apply与call方法在本质上没有太大区别,只不过它们传递给函数的参数方式不同, apply是以数组形式进行参数传递,而call方法可以同时传递多个值.如果某个函数仅能够接收多个参数列表,而现在希望把一个数组的所有元素作为参数进行传递,那么使用apply方法就显得非常便利.function max(){ var m = Number.NEGATIVE_INFINITY; // 声明一个负无穷大的

JS编程建议——74:使用高阶函数

建议74:使用高阶函数高阶函数作为函数式编程众多风格中的一项显著特征,经常被使用.实际上,高阶函数即对函数的进一步抽象.高阶函数至少满足下列条件之一:接受函数作为输入.输出一个函数. 在函数式语言中,函数不但是一种特殊的对象,还是一种类型,因此函数本身是一个可以传来传去的值.也就是说,某个函数在刚开始执行的时候,总可以送入一个函数的参数.传入的参数本身就是一个函数.当然,这个输入的函数相当于某个函数的另外一个函数.当函数执行完毕之后,又可以返回另外一个新的函数,这个返回函数取决于return f

JS编程建议——67:套用函数

建议67:套用函数套用是JavaScript函数一个很有趣的应用.所谓套用就是将函数与传递给它的参数相结合,产生一个新的函数.在函数式编程中,函数本身也是一个值,这种特性允许用户以有趣的方式去操作函数值.例如,在下面代码中定义一个add()函数,该函数能够返回一个新的函数,并把参数值传递给这个新函数,从而实现连加操作.var add = function(n){ return function(m){ return n+m; } }document.writeln(add(2)(3)); //5

JS编程建议——3:减少全局变量污染

建议3:减少全局变量污染定义全局变量有3种方式:在任何函数外面直接执行var语句. var f = 'value'; 直接添加一个属性到全局对象上.全局对象是所有全局变量的容器.在Web浏览器中,全局对象名为window. window.f = 'value'; 直接使用未经声明的变量,以这种方式定义的全局变量被称为隐式的全局变量. f = 'value'; 为方便初学者在使用前无须声明变量而有意设计了隐式的全局变量,然而不幸的是忘记声明变量成了一个非常普遍的现象.JavaScript的策略是让

JS编程建议——8:谨慎使用运算符(1)

建议8:谨慎使用运算符(1)1.用===,而不用==JavaScript有两组相等运算符:===和!==.==和!=.===和!==这一组运算符会按照期望的方式工作.如果两个运算数类型一致且拥有相同的值,那么===返回true,而!==返回false.==和!=只有在两个运算数类型一致时才会做出正确的判断,如果两个运算数是不同的类型,会试图强制转换运算数的类型.转换的规则复杂且难以记忆,具体规则如下: '' == '0' // false 0 == '' // true 0 == '0' //

JS编程建议——11:慎重使用伪数组

建议11:慎重使用伪数组JavaScript没有真正的数组,因此typeof运算符不能辨别数组和对象.伪数组在JavaScript中有很高的易用性,程序员不用给它设置维度,而且永远不用担心产生越界错误,但JavaScript数组的性能相比真正的数组可能更糟糕.要判断一个值是否为数组,必须使用constructor属性,例如: if(value && typeof value === 'object' && value.constructor === Array) { } a

JS编程建议——29:准确使用循环体(1)

建议29:准确使用循环体(1)1.选择正确的循环体在大多数编程语言中,代码执行时间多数消耗在循环的执行上.在一系列编程模式中,循环是最常用的模式之一,因此也是提高性能必须关注的地方之一.理解JavaScript 中循环对性能的影响至关重要,因为死循环或长时间运行的循环会严重影响用户体验.JavaScript定义了4种类型的循环:第一种循环是标准的for循环,与C语言使用同样的语法: for (var i=0; i < 10; i++){ //循环体 } for循环是最常用的循环结构,它由4部分组

JS编程建议——36:警惕字符串连接操作(2)

建议36:警惕字符串连接操作(2)先将两个小字符串合并起来,然后将结果返回给大字符串.创建中间字符串s1 + s2与两次复制大字符串相比,对性能的"冲击"要轻得多.(2)编译期合并在赋值表达式中所有字符串连接都属于编译期常量,Firefox自动地在编译过程中合并它们.在以下这个方法中可看到这一过程: function foldingDemo() { var str = "compile" + "time" + "folding"