基本使用
当调用函数时,如果参数未被赋值或被被赋予undefined
时,则获取默认值,同时默认参数在函数调用时求值。
function add(a, b=3, c=4) {
return a + b + c;
}
add(1, 2, 3); // a=2, b=2, c=3
add(1, 2); // a=1, b=2, c=4
add(1); // a=1, b=3, c=4
add(1, undefined, 3); // a=1, b=3, c=4
由于默认参数在函数调用时求值,所以在可以使用先定义的参数作为后定义参数的默认值
function add(a, b=a) {
return a + b;
}
add(2); // a=2, b=2
但是在引用参数默认值时,先定义的参数不能访问后定义的参数,即引用参数作为默认值时只允许前面的参数
function add(a=b, b) {
return a + b;
}
add(1, 2); // a=1, b=2
add(undefined, 2); // 抛出错误,该错误由于默认参数的临时死区导致
同样由于默认参数在函数调用时求值,如果形参的默认值是一个函数,该函数只有在该形参获取默认值时才会被解析
function getValue() {
console.log(‘action’);
return 4;
}
function add(a, b=getValue()) {
return a + b;
}
add(1, 2); // a=1, b=2
add(1); // a=1, b=4
在这个例子中,第一次调用 add 函数时,由于 b 被赋值为2,所以在控制台不会输出 action,但是在第二调用时 b 没有被赋值,使用默认值调用 getValue,控制台输出 action
我们还可以将 a 传入一个函数获得 b 的值
function getValue(c) {
return 4 + c;
}
function add(a, b=getValue(a)) {
return a + b;
}
add(2); // a=2, b=6
默认参数的临时死区
含义:与 let 类似,定义参数时会为每个参数创建一个新的标识符绑定,该绑定在初始化之前不可被引用,如果试图访问会导致程序抛出错误。当调用函数时,会通过传入值或参数的默认值初始化该参数。
function add(a=b, b=3, c=b) {
return a + b + c;
}
add(1, 2, 3); // a=1, b=2, c=3
add(4); // a=4, b=3, c=3
add(); // 抛出错误
调用 add(1, 2, 3),add(4) 和 add(),相当于执行了下面代码创建a,b,c参数值
// 表示调用 add(1, 2, 3) 时代码
let a = 1;
let b = 2;
let c = 3;
// 表示调用时 add(4) 代码
let a = 4;
let b = 3;
let c = b;
// 表示调用 add() 代码
let a = b;
let b = 3;
let c = b;
调用 add() 时,a 初始化时 b 还没被声明,此时的 b 处于临时死区中,所以会导致程序抛出错误。
注意:函数参数有自己的作用域和临时死区,其与函数体的作用域是各自独立的,所以参数默认值不可以访问函数体内声明的变量。
默认参数值对 arguments 对象的影响
如果一个函数使用了默认参数值,则 arguments 对象的行为都和ES5严格模式下保持一致,即无论如何改变参数的值,都不会影响 arguments 对象。
function add(a, b=3) {
console.log(arguments.length);
console.log(arguments[0] === a);
console.log(arguments[1] === b);
a = 5;
b = 6;
console.log(arguments[0] === a);
console.log(arguments[1] === b);
return a + b;
}
add(2)
上面代码会输出
1
true
false
false
false