JavaScript之默认参数值

可能JavaScript最常见的一个技巧就是关于设定函数参数默认值。
下面我们来看一下一般我们的实现方法,代码如下:

1
2
3
4
5
6
7
8
9
10
function foo(x,y){
x = x || 11;
y = y || 31;
console.log(x+y);
}

foo(); // 11 + 31 = 42
foo(5,6); // 5 + 6 = 11
foo(5); // 5 + 31 = 36
foo(null,6); // 11 + 6 = 17

但是这种代码设计存在着一定的缺陷,比如:如果对于一个参数你需要能够传入被认为是false的值。对于上面的代码,如果我传入一个0。

1
foo(0,42);   //此时打印出来的值是53(即11+42),而并非是42(0+42)

产生53的值的原因是因为,实参传入了一个0值,0在这里是一个假值,所以x || 11的结果就应该为11,而不是传入的x的值0。
要修正这个问题,我们可能又会选择增加更多的检查,其代码如下所示:

1
2
3
4
5
6
7
8
function foo(x,y){
x = (x !== undefined) ? x : 11;
y = (y !== undefined) ? y : 31;
console.log(x + y);
}

foo(0,42); // 0 + 42 = 42
foo(undefined,6); // 11 + 6 = 17

上面的代码意味着除了undefined之外的任何值都可以直接传入,除非你确实需要能够传入undefined。在这种情况下,可以通过它并不存在于数组arguments之中来确定这个参数是被省略的,代码如下所示:

1
2
3
4
5
6
7
8
function foo(x,y){
x = (0 in arguments) ? x : 11;
y = (1 in arguments) ? y : 31;
console.log(x + y);
}

foo(5); // 5 + 31 = 36
foo(5,undefined); // 5 + undefined = NaN

上面的代码,当你不能传递任何值(甚至undefined也不行)来表明“我省略了这个参数”,那么如何省略第一个参数x呢?
foo(,5)这样写起来很吸引人,但是这是不合法的语法。

当我们了解了上面的写法之后,我们如何来写函数的默认参数呢?那就是ES6新增的一个语法来改进为缺失的参数赋默认值的流程,其代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function foo(x=11,y=31){
console.log(x + y);
}

foo(); // 11 + 31 = 42
foo(5,6); // 5 + 6 = 11
foo(0,42); // 0 + 42 = 42

foo(5); // 5 + 31 = 36
foo(5,undefined); // 5 + 31 = 36 注意:在这里undefined被丢失了,然后走的是y的默认值
foo(5,null); // 5 + 0 = 5 注意:在这里null被强制转换为0

foo(undefined,6); // 11 + 6 = 17 注意:在这里undefined被丢失了,然后走的是x的默认值
foo(null,6); // 0 + 6 = 6 注意:在这里null被强制转换为0