妙用 switch(true)
2021/12/25
在需要进行多分支选择时,我们经常使用 switch
语句。大多数情况下,我们的匹配条件 (case
子句) 都是一个常量值。但其实,case
后面还可以是一个任意表达式,这在某些场景下会非常有用。
使用 switch(true)
匹配表达式
switch
语句不仅匹配值还可以匹配表达式。case
子句中的表达式将在匹配前被计算,如果表达式的结果与 switch
后面的值相等,它将被匹配:
switch (true) {
case 1 + 1 === 2:
// case 表达式的结果为 true, 这里的会被执行
// ...
break
default:
// 这里不会被执行
break
}
为什么这很有用
这种模式可以在很多场景下使用,用来取代复杂的 if/else
语句。一个常见场景是数据校验:
const user = {
name: "Nicholas Yang",
email: "yss_2016@outlook.com",
number: "00447123456789"
}
if (!user) {
throw new Error("User must be defined.")
}
if (!user.name) {
throw new Error("User's name must be defined")
}
if (typeof user.name !== "string") {
throw new Error("User's name must be a string")
}
// ...更多校验语句
return user
当校验条件很多时,这种写法看起来很不简洁和直观,但如果用 switch(true)
模式来重写,就会美观很多:
const user = {
name: "Nicholas Yang",
email: "yss_2016@outlook.com",
number: "00447123456789"
}
switch (true) {
case !user:
throw new Error("User must be defined.")
case !user.name:
throw new Error("User's name must be defined")
case typeof user.name !== "string":
throw new Error("User's name must be a string")
// ...more validations
default:
return user
}
还可以将校验标准抽象成函数,以提高可读性:
switch (true) {
case !isDefined(user):
throw new Error("User must be defined.")
case !isString(user.name):
throw new Error("User's name must be a string")
case !isValidEmail(user.email):
throw new Error("User's email address must be a valid email address")
case !isValidPhoneNumber(user.number):
throw new Error("User's phone number must be a valid phone number")
// ...more validations
default:
return user
}
在这种场景下,我个人更推荐使用 switch(true)
的写法。