1. arguments在JavaScript中是怎样一种存在
在JavaScript中,arguments 是一个类似数组的对象, 对应于传递给函数的参数,是当前函数的一个内置属性。arguments非常类似Array,但实际上又不是一个Array实例,除了长度之外没有任何数组属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的数组
let args = Array.prototype.slice.call(arguments);
let args = [].slice.call(arguments);
你还可以使用 Array.from()方法或 spread 运算符将 arguments 转换为真正的数组
let args = Array.from(arguments)
let args = [...arguments];
arguments 对象仅在函数内部有效,在函数外部调用 arguments 对象会出现一个错误。
arguments的typeof返回'object'。
console.log(typeof arguments);
// 'object'
可以使用索引来确定各个arguments的类型。
console.log(typeof arguments[0]);
//这将返回单个参数的typeof。
arguments对象是所有函数中可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数的条目,第一个条目的索引从0开始。
2、arguments对象与函数参数的关系
arguments对象的长度是由实参个数而不是形参个数决定的。形参是函数内部重新开辟内存空间存储的变量,但是其与arguments对象内存空间并不重叠。对于arguments和值都存在的情况下,两者值是同步的,但是针对其中一个无值的情况下,对于此无值的情形值不会得以同步。
function testArg(a,b,c,d,e){
console.log('实参个数: '+arguments.length);
console.log('形参个数: '+testArg.length);
console.log('通过形参调用第一个参数: '+testArg[0]);
console.log('通过实参调用第1个参数: '+arguments[0]);
console.log('通过实参调用第9个参数: '+arguments[8]);
console.log('通过形参名称输出参数: '+a,b,c,d,e);
}
testArg(1,2,3,4,5,6,7,8,9)
由上图可以得知,JavaScript函数形参的个数可以使用函数名的length属性获得;实参的个数则是由arguments对象的length属性得到的。
对于未指明的参数可以通过arguments对象以数组的方式来进行调用!
3、JavaScript arguments对象模拟函数重载
由JavaScript中函数的声明和调用特性,可以看出JavaScript中函数是不能重载的。
但是JavaScript arguments对象使得我们可以模拟函数重载
用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载:
function doAdd() {
if(arguments.length == 1) {
console.log(arguments[0] + 5);
} else if(arguments.length == 2) {
console.log(arguments[0] + arguments[1]);
}
}
doAdd(10); //输出 "15"
doAdd(40, 20); //输出 "60"
当只有一个参数时,doAdd() 函数给参数加 5。如果有两个参数,则会把两个参数相加,返回它们的和。所以,doAdd(10) 输出的是 “15”,而 doAdd(40, 20) 输出的是 “60”。
虽然不如重载那么好,不过已足以避开 ECMAScript 的这种限制。
4、arguments对象的callee属性实现递归
arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。
下例是利用arguments对象的callee属性实现的递归求阶乘的函数
function fac(num){
if(num==1 || num==0){
return 1;
}
return num*arguments.callee(--num);
}
var facResult = fac(4);
console.log(facResult);