11.7 编码风格小建议
本节会提到几个描述参数定义的技巧。很高明,但是也有缺陷:使代码看起来很乱,并且更难理解。
11.7.1 可选参数
我偶尔使用参数默认值 undefined
来标记某个参数是可选的(除非这个参数已经有一个默认值了):
function foo(requiredParam, optionalParam = undefined) {
···
}
11.7.2 必需的参数
在 ECMAScript 5 中,有几种可选方法用于确保提供了必需的参数,但是都显得相当笨拙:
function foo(mustBeProvided) {
if (arguments.length < 1) {
throw new Error();
}
if (! (0 in arguments)) {
throw new Error();
}
if (mustBeProvided === undefined) {
throw new Error();
}
···
}
在 ECMAScript 6 中,你可以(大量)使用默认值来写出更加简洁明了的代码(来自于 Allen Wirfs-Brock 的想法):
/**
* Called if a parameter is missing and
* the default value is evaluated.
*/
function mandatory() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = mandatory()) {
return mustBeProvided;
}
交互模式:
> foo()
Error: Missing parameter
> foo(123)
123
11.7.3 指定最多参数个数
本节展示三种方法来指定最多参数个数。例子中的函数 f
参数个数不超过2 - 如果调用者传入的参数超过2个,会抛出一个错误。
第一个方法是在剩余参数 args
中搜集所有的实参,然后检查它的长度。
function f(...args) {
if (args.length > 2) {
throw new Error();
}
// Extract the real parameters
let [x, y] = args;
}
第二个方法依赖于不想要的参数出现在了剩余参数 empty
中。
function f(x, y, ...empty) {
if (empty.length > 0) {
throw new Error();
}
}
第三种方法使用一个守卫值,如果传入了第三个参数,就得不到守卫值了。警告一点就是如果传入的第三个参数的值是 undefined
,也会触发默认值 OK
。
const OK = Symbol();
function f(x, y, arity=OK) {
if (arity !== OK) {
throw new Error();
}
}
悲剧的是,每一个方法写出的代码都看起来乱糟糟的,并且概念混乱。我倾向于检查 arguments.length
,但是又希望废弃 arguments
。
function f(x, y) {
if (arguments.length > 2) {
throw new Error();
}
}