在 JavaScript 中,设置默认参数值的最有效方法是什么?

3
我知道两种设置默认参数的方法,但我想知道哪种方法更受欢迎。
function Foo(par1, par2)
{
    if(par2 == null)
        par2 = "my default"
}

或者

function Foo(par1, par2)
{
    par2 = par2 || "my default"
}

还有比这两种方法更好的方式吗?

编辑:

我还想知道其他人如何处理多个可选参数,例如: 我们在内部库中有几个类似于此的函数(我认为它们非常丑陋)。

function Foo(par1, par2, par3)
{
    if(par2 == null)
        par2 = "my default"
    if(par3 == null)
        par3 = "my default"
    // Do something
}

并且要调用它:

Foo("Parameter one",null,true)
11个回答

5

第一个实际上是错误的,因为它们将是未定义的而不是 null。

par2 !== null 对于这种情况会返回 true。

由于 JavaScript 在宽松比较时将 null、undefined 和 false 视为相同的值,我建议明确检查 undefined 值。

if (par2 !== undefined)
        par2 = "my default";

或者

    par2 = par2 !== undefined ? par2 : "my default";

这将使您能够传递 false 或 null 等值。

但是,您的第二种方法很方便,但只有在您知道永远不会传递 false 或 null 的情况下才是如此。


Asker正在使用==,而不是===。所以第一个例子实际上并没有错。 - Crescent Fresh
它能够工作,但从实际上来说是错误的,因为他不知道他实际上正在匹配什么。 - jishi

4
更好、更可靠的方法是:
1)验证传递的参数数量(例如,如果你想允许传递未定义的值或 null 值,就像在 DOM insertBefore 函数的情况下),只有在验证之后才尝试设置它们的值,如果省略则使用默认值:
function Foo(par1, par2)
{
    if (arguments.length < 2)
        par2 = "my default"
    else
    if (arguments.length < 3)
        par3 = "my default"
}
2)或者,如果你想禁止传递 undefined 值,在构造函数中包含它:
function Foo(par1, par2)
{
    if (arguments.length < 2 && par2 === undefined)
        par2 = "my default"
    else
    if (arguments.length < 3 && par3 === undefined)
        par3 = "my default"
}
3)或者,如果你想禁止传递 null 值,在构造函数中包含它:
function Foo(par1, par2)
{
    if (arguments.length < 2 && (par2 === undefined || par2 === null))
        par2 = "my default"
    else
    if (arguments.length < 3 && (par3 === undefined || par3 === null))
        par4 = "my default"
}
顺便说一下:我建议避免使用函数重载,在实际中很少有必要使用。

如果你的函数确实接受 null、undefined、0、'' 作为参数,那就很好。 - Pim Jager
Pim,这个问题是一般性的,没有提供任何值的细节,对吧? - Sergey Ilinsky
这不是批评。我只是在说,如果你的函数不需要那些值作为参数,那么你实际上并不需要这个东西。(此外,我赞同你的答案,因为它确实是针对那些情况的好答案。) - Pim Jager

3
我通常使用第二个,因为它添加的信号较少。

2
这个怎么样?
function myFunc(arg1, arg2, arg3) {
    switch (arguments.length) {
        case 0 : arg1 = "default1";
        case 1 : arg2 = "default2";
        case 2 : arg3 = "default3";
    }
}

2

个人认为第二种形式更加简洁易读,肯定比sergey的参数检查更加容易理解,虽然它有其适用场景。但我更喜欢传递可扩展对象而不是维护参数签名。

例如:

function Foo(myArgs)
{
    myArgs.par1 = myArgs.par1 || "my default"
    myArgs.par2 = myArgs.par2 || "my default"
}

如果您的参数表示一个假值(falsy value),那怎么办? - Pablo Cabrera
好问题。如果有必要,我会使用类似jishi的三元运算符 - 但大多数情况下,我发现falsy值是默认值,或者根本不应该传递可疑的值。说实话,我不太确定为什么我在这个问题上得到了采纳,因为我只是用对象参数技术扩展了其他正确答案 :) - annakata
不需要定义myArgs变量。已经有一个内部的arguments变量:请参见http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf中的第10.1.8节。 - some
@some - 我非常清楚这一点,但是创建自己的类可以使您对数据进行集中可重用控制,提供廉价验证、默认值,如果您希望,可以接近类型安全,并提高可读性。相比之下,参数变量实际上是相当混乱和笨拙的。 - annakata
哦,而且更进一步说 - arguments[n] 和 myArgs.foo 几乎不是同一个东西。 - annakata
虽然这与其他几种方法并没有太大的区别,但它似乎是最接近我需要做的事情的匹配。 - chills42

1

1

我所做出的选择取决于参数类型和所需的默认值。

例如,如果par2为false、0、空字符串、null或undefined,则将分配“默认值”:

par2 = par2 || 'default value';

这种行为可能不是预期或所需的。


0

当使用以下解决方案时,你必须考虑的一件事是:

var foo = bar || 123;

bar 的哪些值会被评估为 false。这可能会在未来给你带来问题。

Eric


0

我从未听说过你提到的第二种方法,这很有趣。我会这样做:

function Foo(par1, par2)
{
    par2 = par2 ? par2 : 'default value';
}

但是现在你提到了第二个方法,我认为我会使用它,因为它少打字。


猜数字<0>或值<空字符串>以及许多其他内容都会被错误处理。 - Sergey Ilinsky
不适用于par2=false和默认值=true。请使用undefined如下所示。 - Simon_Weaver

0
如果您使用jQuery,可以这样做:

function foo(params){
 var params = $.extend({}, {bar: '2'}, params);
 alert(params.bar);
}
foo(); //Alerts 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接