ECMAScript的函数参数与大多数语言中的参数有所不同。ECMAScript参数不介意传进来多少个参数,也不介意传进来参数的类型。
也就是说如果你定义了一个只接受两个参数的函数,但是在实际调用函数的时候,你可以传一个参数,两个,三个,甚至不传参数。
之所以这样的原因在于,ECMAScript中的参数在内部是用一个数组来表示的。函数接收的始终是这个数组,而不是这个数组中包含哪些参数(在存在数组的情况下)。
在函数体内部可以通过arguments对象来访问这个参数数组,从而传递给函数每一个参数。
arguments对象只是与数组类似(但是它并不是Array的实例),因为可以使用方括号语法访问到它的每一个元素。使用length可以确定传进来多少个参数。
例如:
function Person(name,age){
this.show = arguments,
this.name = name,
this.age = age,
this.showparameter = function(){
console.log(arguments);
}
}
var person1 = new Person("小胡","20");
console.log(person1.show);//["小胡","20",callee:f,Symbol(Symbol.iterator):f]
person1.showparameter()//[callee:f,Symbol(Symbol.iterator):f]当前运行的函数的执行环境(即函数showparameter)并没有传入参数
ECMAScript函数的一个重要特点:命名参数只提供便利,但不是必需的。
通过访问arguments对象的length属性可以获知有多少个参数传递给了函数。
例如:
function Add(){
console.log(arguments.length);
var num = arguments.length;
if(num == 1){
console.log(arguments[0]+10);
}
if(num == 2){
console.log(arguments[0]+arguments[1]);
}
}
Add(10);//输出 1 20
Add(10,20);//输出 2 30
上面的例子是通过判断传入函数参数的个数,来实现函数的不同功能
arguments可以和命名参数一起使用
例如:
function Add(num1,num2){
console.log(arguments.length);
var num = arguments.length;
if(num == 1){
console.log(arguments[0]+10);
console.log (num2);
console.log(arguments[1]);
console.log(arguments.length);
}
if(num == 2){
console.log(arguments[0]+num2);//arguments对象可以和命名参数一起使用
}
}
Add(10);//输出 1 20 undefined undefined 1
Add(10,20);//输出 2 30
argumrnts参数的值永远与对应命名参数的值保持一致
例如:
function doAdd(){
arguments[1] = 10;
console.log(arguments[0]+num2);
}
每次执行这个函数都会重写第二个参数,将第二个参数的值修改为10。因为,arguments对象中的值会反映到对应的参数中去,所以,修改arguments[1]也就是修改了num2,结果它们的值都会变为10。单着并不意味着两者访问同一片内存空间,它们的内存空间是独立的,但是它们的值是同步的。
如果只传入了一个参数,那么arguments[1]设置的值是不会反映到命名参数中。因为arguments对象的长度是由传入参数的个数决定的,不是由定义时函数的命名参数的个数来决定的
例如:
function Add(num1,num2){
var num = arguments.length;
if(num == 1){
arguments[1] = 1;
console.log(num2);
console.log(arguments.length);
console.log(arguments[1]);
}
if(num == 2){
console.log(arguments[0]+num2);
}
}
Add(10);//输出 undefined 1 1
//num2未定义,arrguments的长度是根据传入实参的个数来决定的