一、命名参数与实际传参
定义函数时虽然确定了参数个数,但是当你在调用这个函数的时候,你可以少传参、多传参或者不传参,解析函数时都不会报错。原因是:ECMAScript中的参数在内部是使用数组来表示的。函数接收到的始终都是arguments这个数组。
function sayHi() {
alert("arg1=" + arguments[0] + "," + "arg2=" + arguments[1]);
}
此现象说明:命名的参数只是提供便利,但不是必需的。
通过访问arguments的length,可以获得有几个参数传递给了函数。并且arguments对象可以与命名参数一起使用。
function doAdd(num1, num2, num3) {
if (arguments.length === 1) {
alert(num1 + 1);
}
else if (arguments.length === 2) {
alert(arguments[0] + num2);
}
else if (arguments.length === 3) {
alert("arguments.length=" + arguments.length)
}
}
doAdd(10); //11
doAdd(10, 20); //30
上图代码,在执行doAdd(10, 20)时不会走入第三个if语句中,而是走入了第二个if语句中,是因为arguments对象的长度是由传入参数的个数决定的,不是由定义函数时的命名参数个数决定的。没有传递值的命名参数将自动赋值undefined。
二、参数传递方式
ECMAScript中所有参数传递都是值传递,不可能通过引用传递参数。把函数外部的值复制给函数内部的参数,与把值从一个变量复制到另一个变量一样。
function setName(obj) {
obj.name = "aaa";
obj = new Object();
obj.name = "bbb";
}
var person = new Object();
setName(person);
alert(person.name); //"aaa"
如上面代码所示,person传入后在函数内部,修改obj.name为"aaa", 显示的是"aaa",说明引用参数传递时是将外部参数指向的对象地址复制到内部局部参数(在函数执行完毕后销毁),其指向的对象不变,所以更改了name后,person.name为最新的值。
如果person按引用传递,person就会被自动修改为指向name="bbb"的新对象。