使用带有 fallthrough 的开关来处理 Javascript 中的默认参数是个好主意吗?

Posted

技术标签:

【中文标题】使用带有 fallthrough 的开关来处理 Javascript 中的默认参数是个好主意吗?【英文标题】:Is it a good idea to use a switch with fallthrough to handle default arguments in Javascript? 【发布时间】:2012-02-03 08:50:37 【问题描述】:

我最近了解到,您可以使用带有 fallthrough 的简洁 switch 语句来设置 javascript 中的默认参数值:

function myFunc(arg1, arg2, arg3) 
    //replace unpassed arguments with their defaults:
    switch (arguments.length) 
        case 0 : arg1 = "default1";
        case 1 : arg2 = "default2";
        case 2 : arg3 = "default3";
    

我已经越来越喜欢它了,因为它不仅很短,而且它还可以根据实际传递的参数工作,而不依赖于将一类特殊的值(null、falsy 等)用作占位符,如更传统的版本:

function myFunc(arg1, arg2, arg3)
    //replace falsy arguments with their defaults:
    arg1 = arg1 || "default1";
    arg2 = arg2 || "default2";
    arg3 = arg3 || "default3";

在看到使用开关的版本后,我最初的想法是我应该考虑“默认”使用它而不是 || 版本。

switch fallthough 使它不会更长,它的优点是它更“健壮”,因为它不关心参数的类型。在一般情况下,每当我必须使用默认参数创建函数时,不必担心所有虚假值(''、0、null、false ...)会发生什么,这听起来是个好主意。

然后,我会将arg = arg || x 保留用于我想要检查真实性而不是将其重新用作参数默认的一般规则的实际情况。

但是,当我为它创建 code search 时,我发现了这种模式的 very few 示例,因此我不得不戴上怀疑的帽子。 为什么我没有找到更多这个成语的例子?

现在是不是很出名了? 是不是我搜索的不够好?我是否对大量误报感到困惑? 有什么东西使它不如替代品吗?

我(和一些 cmets)可以想到避免 switch(arguments.length) 的一些原因:

使用通过对象字面量传递的命名参数非常灵活且可扩展。也许更多参数可以是可选的地方正在使用它?

也许大多数时候我们确实想要检查真实性?使用一类值作为占位符还允许默认参数出现在中间而不是只出现在末尾:myFunc('arg1', null, 'arg3')

也许大多数人只是喜欢很短的arg = arg || "default",而大多数时候我们只是不关心虚假值?

也许访问arguements 是邪恶的/性能不佳的?

也许这种开关盒故障有一个我没有想到的坏部分?

这些缺点是否足以避免使用 switch(arguments.length) 作为主要的默认参数模式,还是我应该在代码中保留和使用的巧妙技巧?

【问题讨论】:

我从来不知道这个成语,但看看它至少有一个警告我可以看到 - 传递 undefined 使 arguments.length === 2,而您可能想用传递的 undefined 替换默认值也是如此(就像|| 一样)。 有趣的方法。虽然它只有在始终提供所有前面的参数时才有效。比如jQuery允许你省略中间的参数,比如$.get(url, callback)而不是$.get(url, data, callbacl)switch 无法区分不同的参数类型。如果传递了“填充参数”,它也会失败,例如foo(1, null, 3),因为想要设置第三个参数而不是第二个参数(edit pimvdb 所说的)。所以也许这些就是它不那么受欢迎的原因;不够灵活。 我认为不使用它的另一个原因是,如果您将方法重构为具有不同的签名,而典型方法仍然可以正常工作,则需要额外的工作。 请编辑您的问题并澄清。 是的,我认为没有充分的理由关闭它,更不用说保证两个 cmets 相隔 5 分钟了,因为这是一个多么糟糕的问题。 【参考方案1】:

由于问题已经更新,这确实是一个见仁见智的问题。许多人建议避免使用许多 javascript 功能,例如 switch 和三元。这就是为什么没有很多关于其中一些功能的信息的原因。

提出建议的原因是许多人误用了这些功能并在他们的代码中产生了问题。这些错误有时很难检测到,其他人可能很难理解您的代码在做什么(尤其是那些不熟悉 javascript 或新程序员的人)。

因此,如果您喜欢这样做,并且您不必担心任何处理您的代码的人的意见(或技能水平)。无论如何,你的方法会奏效。我自己有时也会使用 switch 语句,虽然我不认为它真的“好”或“坏”,但很难找到需要它的情况。

你问我如何在没有 if-else 链的情况下解决这个问题:

function myFunc(args) 
    var allArgs = 
        arg1:"default1",
        arg2:"default2",
        arg3:"default3"
    ;
    for (var key in args) 
        allArgs[key] = args[key];        
    

myFunc(arg1:null, arg3:'test')

【讨论】:

我认为 switch 模式更适合当函数从f(arg1, arg2) 中的列表接收参数时。但是你有必要说整个讨论是无关紧要的,因为命名参数通常更好。【参考方案2】:

只是一个猜测,但 Doug Crockford 不鼓励在“JavaScript:优秀部分”中使用 switch 语句。他的逻辑是 switch 语句是错误的常见来源,因为在使用“失败”逻辑时很难找到它们。何时触发案例很容易看出,但通常很难确定结果集中的每个案例是否都已被覆盖,尤其是当它不是您的代码时。

【讨论】:

+1 可能有更好的方法可以在不使用 switch 语句的情况下完成您想要做的事情。关于 javascript 的好与坏部分的一些信息:youtube.com/watch?v=RO1Wnu-xKoY @NickHagianis:这里有什么替代方案?通常的|| 样式具有不同的语义(如问题中所讨论的那样),使用if-else要详细得多 这是对这个问题的一个很好的回答:“为什么我没有找到更多这个成语的例子?”但我不确定逻辑是否成立。许多 JavaScript 程序员似乎认为 Crockford 关于 JavaScript 哪些部分是“好”和“坏”的观点是普遍正确的。就个人而言,我不同意 Crockford 的观点:switch 语句可能很古怪,但我从未发现它们是使用它们的任何代码中的重要错误来源。

以上是关于使用带有 fallthrough 的开关来处理 Javascript 中的默认参数是个好主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

go语音基础之switch语句 和 fallthrough 用途

nginx编译下出现error: this statement may fall through [-Werror=implicit-fallthrough=]

Golang的fallthrough与switch的坑

如何修复此语句可能会通过 [-Werror=implicit-fallthrough=]?

go 的fallthrough特征

C++关键字之fallthrough