似乎最安全的方法 - 在决定使用 default - 检查被调用函数中是否存在可选参数。
依赖于参数对象成员的创建,如果参数丢失,它甚至不会被创建,不管它可能被声明,我们可以这样编写你的函数:
function myFunc(requiredArg, optionalArg){
optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
//do stuff
}
利用这种行为:
当我们需要确保函数获得其过程中所需的某个值时,我们可以安全地任意明确地检查参数列表中的任何缺失值。
在下面的演示代码中,我们会特意把一个typeless和valuelessundefined作为默认值能够确定它是否可能在错误的参数值(例如 0 false 等)上失败,或者它的行为是否符合预期。
function argCheck( arg1, arg2, arg3 ){
arg1 = 0 in arguments || undefined;
arg2 = 1 in arguments || false;
arg3 = 2 in arguments || 0;
var arg4 = 3 in arguments || null;
console.log( arg1, arg2, arg3, arg4 )
}
现在,检查一些虚假的参数值,看看它们的存在是否被正确检测到并因此评估为 true:
argCheck( "", 0, false, null );
>> true true true true
这意味着 - 他们没有未能识别/作为预期的参数值。
在这里,我们检查了所有参数是否丢失,根据我们的算法,即使它们是 falsy,它们也应该获取它们的默认值。
argCheck( );
>> undefined false 0 null
如我们所见,参数 arg1、arg2、arg3 和未声明的 arg4 正在返回它们的确切 默认值 值,按顺序排列。
因为我们现在已经确保它可以工作,所以我们可以重写函数,它实际上可以像第一个示例中那样使用它们,方法是:if 或三元条件。
对于具有多个可选参数的函数,- 循环,可能会为我们节省一些代码。但是由于参数 names 如果没有提供它们的值就不会被初始化,即使我们以编程方式编写了默认值,我们也不能再通过名称访问它们,我们可以只能通过 arguments[index] 访问它们,这在代码可读性方面无用。
但除了在某些编码情况下可能完全可以接受的这种不便之外,对于多个和任意数量的参数默认值,还有另一个无法解释的问题。这可能而且应该被认为是一个错误,因为我们不能再跳过参数,因为我们曾经可以在不给出值的情况下使用如下语法:
argCheck("a",,22,{});
因为它会抛出!这使得我们不可能用我们想要的默认值的特定 falsy 类型来替换我们的参数。
这很愚蠢,因为 arguments 对象 是一个类似数组的对象,并且预计会按原样支持这种语法和约定,无论是原生还是默认!
由于这个短视的决定,我们不再希望编写这样的函数:
function argCheck( ) {
var _default = [undefined, 0, false, null ],
_arg = arguments;
for( var x in _default ) {
x in _arg ? 1 : _arg[x] = _default[x];
}
console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
}
在这种情况下,我们将能够在参数行中写入所需类型的每个默认值,并且至少能够通过 args.index 访问它们。
例如这个函数调用会产生:
argCheck();
>>undefined 0 false null
在我们的默认参数值数组中定义。
但是以下仍然是可能的:
argCheck({})
>>Object { } 0 false null
argCheck({}, [])
>>Object { } Array [ ] false null
但很遗憾没有:
argCheck("a",,,22);
>>SyntaxError: expected expression, got ','
否则会记录:
>>a 0 false 22
但那是一个更好的世界!
但是 - 对于原始问题 - 最顶层的功能就可以了。
例如:
function argCheck( arg, opt ) {
1 in arguments ? 1 : opt = "default";
console.log( arg, opt );
}
p.s.:很抱歉在编写它们时没有在我的参数输入中保留所选默认值的 types。