arguments类数组对象
------------ ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。
--------------------------JS函数没有真正意义上的重载。
在函数内部有两个特殊的对象 : arguments和this。
当函数被调用时,传入的参数将保存在arguments类数组对象中,通过arguments可以访问所有该函数被调用时传递给它的参数列表。
arguments并不是一个真正的数组,而是一个“类似数组(array-like)”的对象,因为arguments拥有一个length属性,但它缺少所有的数组方法。
通过arguments可以实现一个add()函数,把传入的参数进行加法运算并把值返回:
function add(){ var sum = 0; for(var i = 0, l = arguments.length; i < l; i++){ sum += arguments[i]; } return sum; }
虽然arguments的主要用途是保存函数参数,但这个对象还有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数。
使用该属性可以实现一个阶乘函数:
function factorial(num){ if (num <= 1) { return 1; } else{ return num * arguments.callee(num - 1); } }
arguments[i]的值会与对应的命名参数的值保持同步。
function add(num1, num2){ arguments[1] = 10; return arguments[0] + num2; }
add(2,2); // 12
执行add()函数会重写第二个参数,将第二个参数的值改为10。 但修改命名参数的值不会影响到arguments中对应的值。
同时,arguments.length是由传入的参数个数决定的,而不是由定义函数时的命名参数的个数决定的。
注意:
在严格模式下,
- 像上面那样把arguments[1]设置为10,num2的值仍然不变。重写arguments的值会导致语法错误
- 不能使用argumengs.callee
像下面形式的函数,在严格模式下会报错。
function factorial(num){ if (num <= 1) { return 1; } else{ return num * arguments.callee(num - 1); } }
解决方法:
var factorial = (function f(num){ if(num <= 1){ return 1; }else{ return num*f(num-1); } });