定义
由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。这就是arguments对象的由来。(个人理解为调用时可以传入任意数量的参数而不是定义时的参数个数,所以需要arguments)
虽然arguments对象并不是一个数组,但是访问单个参数的方式与访问数组元素的方式相同,arguments
对象包含了函数运行时的所有参数,arguments[0]
就是第一个参数,arguments[1]
就是第二个参数,以此类推。
ps:这个对象只有在函数体内部,才可以使用。
ex:
// arguments对象
function arg(parameter){
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
arg(2,3)
打开控制台可以看见
即 使用arguments
不需要明确指出参数名就可以访问传入的参数。
正常模式和严格模式下参数的修改
正常模式
function arg1(a,b){
arguments[0] = 9;
arguments[1] = 19;
return a + b
}
console.log(arg1(2,3))
打开控制台
可以看见函数调用时传入的参数,在函数内部被修改成19和9,结果自然也发生了变化。
严格模式
function arg1(a,b){
'use strict'; // 开启严格模式
arguments[0] = 9;
arguments[1] = 19;
return a + b
}
console.log(arg1(2,3)) //结果为5
严格模式下,arguments对象与函数参数不具有联动关系。这时修改arguments对象,不会影响到真实参数a和b。
arguments对象解决的问题
解决同名参数的问题
在js中,规定了如果有同名的参数,则取最后出现的那个值
ex:
function same(a,a){
console.log(a)
}
same(1,2) //结果为2
在上面的例子中,即使后面的a没有值或被省略,也是以其为准。
ex:
function same(a,a){
console.log(a)
}
same(1) //结果为undefined
在上面的例子中,由于没有提供第二个参数,a的取值就变成了undefined
这么看来好像就不能取到前面参数的值啦,其实不然,此时便可用arguments
解决这个问题。
ex:
function same(a,a){
console.log(arguments[0])
}
same(1) //结果为1
打开控制台,可以看见此时的结果为1,获取到了第一个参数
判断函数调用时带几个参数的问题
在js中,函数的length属性返回的是函数预期传入的参数个数,即函数定义之中的参数个数。即不管调用时输入了多少个参数,length属性始终等于函数定义之中的参数个数。
ex:
function func(a,b){
return a;
}
console.log(func(1,2,3))//结果为1
console.log(func(1)) //结果为1
console.log(func()) //结果为undefined
console.log(func.length); //结果为2
打开控制台
可以看见,无论调用时传入了多少参数,length属性始终等于函数定义之中的参数个数2。
而为了判断函数调用时到底带几个参数,就需要用到arguments
对象啦。
ex:
function func1(){
return arguments.length
}
console.log(func1()); //0
console.log(func1(1)); //1
console.log(func1(1,2,3)); //3
打开控制台
可以看见,通过arguments对象的length属性,我们就可以判断函数调用时到底带几个参数啦。
arguments对象的其他属性与知识
callee 属性
该属性会返回它所对应的原函数,即指向当前执行的函数。
ex:
var f = function () {
console.log(arguments.callee === f);
}
f() // true
可以通过arguments.callee,达到调用函数自身的目的,实现斐波那契数列等。但是这个属性在严格模式里面是禁用的,因此不建议使用。
arguments对象与数组的关系
虽然arguments很像数组,但是数组的一些专有的方法(比如slice和forEach),不能在arguments对象上直接使用,如果需要使用这些方法,可以通过调用call方法或者重新填充为新数组进行使用
ex:
var args = Array.prototype.slice.call(arguments);
//填充为新数组
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
ps:instanceof
运算符可以区分数组和对象
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true