1.参数是按顺序传递的,参数的默认值可以赋给任意位置的参数,给参数传undefined,参数才会使用默认值,例子如下:
function foo(a, b = 2, c = 3) {
console.log(a, b, c);
}
foo() //undefined 2 3
foo(1, null, undefined) // 1 null 3
function bar(a, b = 2, c) {
console.log(a, b, c);
}
bar(1, 3); //1 3 undefined
bar(1, undefined, 3);//1 2 3
2.参数默认值修改了arguments的行为。arguments可以获取到函数参数列表,在严格模式下,修改了形参的值不影响arguments,但是非严格模式下,并且没有参数默认值的时候,修改了形参的值,arguments里对应的值也被修改了。另外arguments.length的取值是实际传给函数的参数个数。
function mixArgs(a, b) {
console.log(arguments.length);
console.log(a === arguments[0]);
console.log(b === arguments[1]);
a = 'alpha';
b='beta';
console.log(a === arguments[0]);
console.log(b === arguments[1]);
}
mixArgs(1, 2);
// 3
// true
// true
// true
// true
"use strict";
function mixArgs2(a, b) {
console.log(arguments.length);
console.log(a === arguments[0]);
console.log(b === arguments[1]);
a = 'alpha';
b='beta';
console.log(a === arguments[0]);
console.log(b === arguments[1]);
}
mixArgs2(1, 2);
// 3
// true
// true
// false
// false
function mixArgs3(a, b=2) {
console.log(arguments.length);
console.log(a === arguments[0]);
console.log(b === arguments[1]);
a = 'alpha';
b='beta';
console.log(a === arguments[0]);
console.log(b === arguments[1]);
}
mixArgs3(1, 2);
// 3
// true
// true
// false
// false
3.参数默认值修改了函数的length的行为。length是函数声明的形参数量。但是当函数参数有默认值的时候,函数的length是函数参数第一个默认值前面的参数个数
function foo(a, b =2, c) {}
console.log(foo.length); // 1
function foo1(a, b , c = 2) {}
console.log(foo1.length); // 2
4.默认值表达式。
函数的参数除了可以赋字面量外,还可以赋值表达式。表达式是在调用函数的时候运行。
let n = 1;
function getValue() {
return n++;
}
function test(a, b = getValue()) {
console.log(a, b);
}
test(1,2);// 1,2
test(1); //1 ,1 n:2
test(1); //1 ,2 n:3
test(1); //1 ,3 n:4
test(1); //1 ,4 n:5
5.参数默认值的暂时性死区
在let const变量声明之前有一个暂时性死区,是不能使用变量的。
console.log(a);
let a =1; // ReferenceError: Cannot access 'a' before initialization
a变量有提升,但是为了不让变量声明前使用,才出来暂时性死区。参数默认值也是有暂时性死区
function getValue(v) {
return v * 2;
}
function foo(a, b = getValue(a)) {
console.log(a, b);
}
foo(1);// 1,2
//调用的时候 会运行
// let a=1;
// let b=getValue(a);
// 这段代码是合理的
foo(2);//2,4
function bar(a = getValue(b), b) {
console.log(a, b);
}
bar(undefined, 1);// ReferenceError: Cannot access 'b' before initialization
//调用的时候 会运行
// let a=getValue(b);
// let b=1;
// 变量b在声明前使用了,导致错误