我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
当前回答
我认为这是最简单、最易读的方法:
if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here
保罗·迪克森(Paul Dixon)的回答(我个人认为)不如这一点可读,但归根结底是偏好。
impin的答案要高级得多,但对于大函数来说更有用!
2013年11月17日晚上9:33编辑:我为Node.js创建了一个包,它可以更容易地“重载”称为参数化的函数(方法)。
其他回答
似乎最安全的方法-在决定使用默认值之前处理所有提供的错误类型的参数-是检查所调用函数中是否存在可选参数。
依赖于arguments对象成员创建(如果缺少参数,甚至不会创建),无论它可能被声明,我们都可以这样编写函数:
function myFunc(requiredArg, optionalArg){
optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
//do stuff
}
利用此行为:每当我们需要确保函数获得其过程中所需的某个值时,我们都可以安全地检查参数列表中的任何缺失值。
在下面的演示代码中,我们将故意将一个无类型和无值的undefined作为默认值,以便能够确定它是否会在错误的参数值(如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 )
}
现在,检查几个错误的参数值,看看是否正确检测到它们的存在,并因此计算为真:
argCheck( "", 0, false, null );
>> true true true true
这意味着-它们没有将/识别为预期的参数值。这里我们检查了所有参数的缺失,根据我们的算法,即使它们是假的,也应该获取它们的默认值。
argCheck( );
>> undefined false 0 null
如我们所见,参数arg1、arg2、arg3和未声明的arg4按顺序返回其确切的默认值。因为我们现在已经确定了它的有效性,所以我们可以重写函数,该函数实际上可以像第一个示例中那样使用它们,方法是使用if或三元条件。
对于具有多个可选参数的函数,-循环,可能会为我们节省一些时间。但是,由于如果不提供参数名称的值,则参数名称不会被初始化,因此即使我们以编程方式编写了默认值,我们也无法再通过名称访问它们,因此只能通过参数[索引]访问它们,这对代码的可读性来说是无用的。
但除了在某些编码情况下可能完全可以接受的这种不便之外,还有一个未知的问题,即多个任意数量的参数默认值。这可能也应该被认为是一个错误,因为我们不能再跳过参数,因为我们曾经可以在不提供值的情况下,使用如下语法:
argCheck("a",,22,{});
因为它会扔!这使得我们无法用所需默认值的特定错误类型替换参数。这是愚蠢的,因为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] );
}
在这种情况下,我们将能够在arguments行中写入所需类型的每个默认值,并且至少能够通过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.:很抱歉,在编写参数输入时没有保留所选默认值的类型。
如果需要插入一个NULL,那么可能会遇到一些问题。除此之外,不,我认为你可能走上了正确的轨道。
有些人选择的另一种方法是使用一个变量的assoc数组在参数列表中迭代。它看起来有点整洁,但我想它有点(非常少)更需要处理/内存。
function myFunction (argArray) {
var defaults = {
'arg1' : "value 1",
'arg2' : "value 2",
'arg3' : "value 3",
'arg4' : "value 4"
}
for(var i in defaults)
if(typeof argArray[i] == "undefined")
argArray[i] = defaults[i];
// ...
}
我不知道为什么@Paul的回复被否决,但对null的验证是一个不错的选择。也许一个更肯定的例子会更有意义:
在JavaScript中,缺少的参数就像未初始化的声明变量(仅vara1;)。相等运算符将undefined转换为null,因此这对于值类型和对象都非常有效,这就是CoffeeScript处理可选参数的方式。
function overLoad(p1){
alert(p1 == null); // Caution, don't use the strict comparison: === won't work.
alert(typeof p1 === 'undefined');
}
overLoad(); // true, true
overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator.
overLoad(10); // false, false
function overLoad(p1){
if (p1 == null) p1 = 'default value goes here...';
//...
}
不过,有人担心,最好的语义是typeof variable==“undefined”稍微好一点。我不会为这一点辩护,因为这是底层API如何实现函数的问题;它不应该引起API用户的兴趣。
我还应该补充一点,这是物理上确保遗漏任何参数的唯一方法,使用in运算符,不幸的是,它无法处理参数名称,因此必须传递参数索引。
function foo(a, b) {
// Both a and b will evaluate to undefined when used in an expression
alert(a); // undefined
alert(b); // undefined
alert("0" in arguments); // true
alert("1" in arguments); // false
}
foo (undefined);
如果您正在使用Undercore库(您应该这样做,这是一个很棒的库):
_.defaults(optionalArg, 'defaultValue');
松散类型检查
易于编写,但0、“”、false、null和undefined将转换为默认值,这可能不是预期的结果。
function myFunc(requiredArg, optionalArg) {
optionalArg = optionalArg || 'defaultValue';
}
严格的类型检查
更长,但涵盖大多数情况。只有当我们传递undefined作为参数时,它才会错误地分配默认值。
function myFunc(requiredArg, optionalArg) {
optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue';
}
正在检查参数变量
能捕捉所有的情况,但写起来最笨拙。
function myFunc(requiredArg, optionalArg1, optionalArg2) {
optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue';
optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue';
}
ES6
不幸的是,目前浏览器支持非常差
function myFunc(requiredArg, optionalArg = 'defaultValue') {
}