我有一个 switch 语句,它根据当前 url 路径运行逻辑。它有一个默认情况,如果其他情况都不匹配,则考虑计算值(例如正则表达式匹配):
const pathname = document.location.pathname;
switch (pathname) {
case "/foo": //...
case "/bar": //...
case "/baz": //...
default:
if (/^\/user\/\w+\/likes/.test(pathname)) {
// ...
}
else if (/^\/blog\/\d+/.test(pathname)) {
// ...
}
}
有人建议我更改它以省略default
并使用条件作为我的情况:
switch (true) {
case pathname === "/foo": //. ..
case pathname === "/bar": // ...
case pathname === "/baz": // ...
case /^\/user\/\w+\/likes/.test(pathname): // ...
case /^\/blog\/\d+/.test(pathname): // ...
}
我想确定其中哪一个具有更好的运行时复杂性。老实说,我以前从未见过这样的东西,所以我不知道它是如何工作的。我知道Java将 switch 语句编译为查找表,但 JavaScript 未编译,因此它可能不使用查找表。
如果 JS确实使用查找表,第一个选项(使用default
)可能会执行得更好,因为 case 语句都使用可以散列的常量值。如果它指出在匹配之前评估表达式是正确的,那么第二个可能会表现更差(取决于表达式的数量)。
那么为什么其中一个的运行时复杂度可能比另一个更好呢?它到底是如何工作的?
它们都具有相同的运行时复杂性。它们与匹配表达式的数量呈线性关系,且匹配表达式的数量是恒定的。
它并没有说在匹配任何表达式之前都会对所有表达式进行求值。
case
这篇文章只是想强调case
计算任何表达式,而不是仅使用常量文字。尽管如此,表达式还是被一个接一个地求值和匹配;如果前一个已经匹配,则根本不会评估它们case
。switch (true)
被许多人劝阻并视为不好的做法。最好使用普通的if
/else
链,它的工作原理是一样的,但更容易理解: