ES6 默认参数

函数默认参数,在ES6中,可以为函数的采纳数指定默认值。函数默认参数允许在没有值或undefined被传入时使用默认形参。

1
2
3
4
5
6
7
function log(x,y = "world"){
console.log(x,y);
}

log('Hello') // Hello world
log('hello','china') // hello china
log('hello','') // hello

默认参数使用注意点

  1. 参数变量是默认声明的,所以不能用let或const再次声明。
1
2
3
4
function foo(x = 5) {
let x = 1; // Identifier 'x' has already been declared
const x = 2; // error
}
  1. 使用参数默认值时,函数不能有同名参数
1
2
3
4
5
6
7
8
9
10
// 不报错
function foo(x, x, y) {
// ...
}

// 报错
function foo(x, x, y = 1) {
// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context
  1. 显式传入undefined或不传值时使用函数默认参数值,传入’’或null时使用传入的参数值。
1
2
3
4
5
6
7
8
9
10
11
function test (num = 1){
console.log(typeof num);
}

test(); // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)

// test with other falsy values:

test('') // 'string' (num is set to '')
test(null) // 'object' (num is set to null)
  1. 参数默认值不是传值的,而是字函数被调用时,参数默认值才会被解析。
1
2
3
4
5
6
7
function append(value, array = []){
array.push(value);
return array;
}

append(1); // [1]
append(2); // [2], not [1,2]
  1. 位置在前的默认参数可用于后面的默认参数
1
2
3
4
5
6
function greet (name,greeting,message = greeting + '' + name){
return [name,greeting,message];
}

greet('David', 'Hi') // ['David', 'Hi', 'Hi', 'Hi David']
greet('David', 'Hi', 'Happy birthday!'); // ['David', 'Hi', 'Happy Birthday!']
  1. 通常情况下,定义了默认值的参数,应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数。如果非尾部的参数设置默认值,实际上这个参数是没法省略的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 例一
function f(x = 1, y) {
return [x, y];
}

f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 报错
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]
  1. 指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。后文的 rest 参数也不会计入length属性。
1
2
3
4
5
6
7
8
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2

(function(...args) {}).length // 0

(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1

剩余(rest)参数

ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

1
2
3
4
5
6
7
8
9
10
11
function add(...values) {
let sum = 0;

for (var val of values) {
sum += val;
}

return sum;
}

add(2, 5, 3) // 10

rest 参数使用注意点

  1. rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
1
2
3
4
// 报错
function f(a, ...b, c) {
// ...
}
  1. 函数的length属性,不包括 rest 参数。
1
2
3
(function(a) {}).length  // 1
(function(...a) {}).length // 0
(function(a, ...b) {}).length // 1
  1. rest参数可以被解构,这意味着他们的数据可以被解包到不同的变量中。
1
2
3
4
5
6
7
function f(...[a, b, c]) {
return a + b + c;
}

f(1) // NaN (b and c are undefined)
f(1, 2, 3) // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)

rest参数和 arguments对象的区别

  • rest参数只包含那些没有对应形参的实参,而arguments对象包含了传给函数的所有实参。

  • arguments对象不是一个真正的数组,而rest参数是真正的Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop。

  • arguments对象还有一些附加的属性 (如callee属性)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

{
// ES5\ES3 默认参数的写法
function f(x, y, z) {
if (y === undefined) {
y = 7;
}
if (z === undefined) {
z = 42
}
return x + y + z
}
console.log(f(1, 3));
} {
// ES6 默认参数
function f(x, y = 7, z = 42) {
return x + y + z
}
console.log(f(1, 3));
} {
function checkParameter() {
throw new Error('can\'t be empty')
}
function f(x = checkParameter(), y = 7, z = 42) {
return x + y + z
}
console.log(f(1));
try {
f()
} catch (e) {
console.log(e);
} finally {}
} {
// ES3,ES5 可变参数
function f() {
var a = Array.prototype.slice.call(arguments);
var sum = 0;
a.forEach(function(item) {
sum += item * 1;
})
return sum
}
console.log(f(1, 2, 3, 6));
} {
// ES6 可变参数
// ... 扩展运算符
function f(...a) {
var sum = 0;
a.forEach(item => {
sum += item * 1
});
return sum
}
console.log(f(1, 2, 3, 6));
} {
// ES5 合并数组
var params = ['hello', true, 7];
var other = [1, 2].concat(params);
console.log(other);
} {
// ES6 利用扩展运算符合并数组
var params = ['hello', true, 7];
var other = [
1, 2, ...params
];
console.log(other);
}