(一)函数默认参数
在 ES6 中, 可以为函数的参数指定默认值. 函数默认参数允许在没有值或 undefined 被传入时使用默认形参.
- function log(x, y = 'World') {
- console.log(x, y);
- }
- log('Hello') // Hello World
- log('Hello', 'China') // Hello China
- log('Hello', '') // Hello
默认参数使用注意点
参数变量是默认声明的, 所以不能用 let 或 const 再次声明.
- function foo(x = 5) {
- let x = 1; // error
- const x = 2; // error
- }
使用参数默认值时, 函数不能有同名参数.
- // 不报错
- function foo(x, x, y) {
- // ...
- }
- // 报错
- function foo(x, x, y = 1) {
- // ...
- }
- // SyntaxError: Duplicate parameter name not allowed in this context
显式传入 undefined 或不传值时使用函数默认参数值; 传入''或 null 时使用传入的参数值.
- 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)
参数默认值不是传值的, 而是在函数被调用时, 参数默认值才会被解析.
- function append(value, array = []) {
- array.push(value);
- return array;
- }
- append(1); //[1]
- append(2); //[2], not [1, 2]
位置在前的默认参数可用于后面的默认参数.
- function greet(name, greeting, message = greeting + ' ' + name) {
- return [name, greeting, message];
- }
- greet('David', 'Hi'); // ["David", "Hi", "Hi David"]
- greet('David', 'Hi', 'Happy Birthday!'); // ["David", "Hi", "Happy Birthday!"]
通常情况下, 定义了默认值的参数, 应该是函数的尾参数. 因为这样比较容易看出来, 到底省略了哪些参数. 如果非尾部的参数设置默认值, 实际上这个参数是没法省略的.
- // 例一
- 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]
指定了默认值以后, 函数的 length 属性, 将返回没有指定默认值的参数个数. 如果设置了默认值的参数不是尾参数, 那么 length 属性也不再计入后面的参数了. 后文的 REST 参数也不会计入 length 属性.
- (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 参数搭配的变量是一个数组, 该变量将多余的参数放入数组中.
- function add(...values) {
- let sum = 0;
- for (var val of values) {
- sum += val;
- }
- return sum;
- }
- add(2, 5, 3) // 10
REST 参数使用注意点
REST 参数之后不能再有其他参数(即只能是最后一个参数), 否则会报错.
- // 报错
- function f(a, ...b, c) {
- // ...
- }
函数的 length 属性, 不包括 REST 参数.
- (function(a) {
- }).length // 1
- (function(...a) {
- }).length // 0
- (function(a, ...b) {
- }).length // 1
REST 参数可以被解构, 这意味着他们的数据可以被解包到不同的变量中.
- 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 属性).
来源: http://www.jianshu.com/p/9078fdffd810