如何在JavaScript中使用对象字面量的形式去编写复杂的条件?

115 阅读3分钟

本文结合了自己的理解进行了意译,如有需要,可查看原文,附址:medium.com/getpowerpla…

在JavaScript中编写一个复杂的表达式有可能会潜在的产生的一些丑陋的代码。一个很长的if/else语句或者switch case语句会是代码变得臃肿。

当有多个情况时,我发现使用对象字面量的形式去解构代码有更好的阅读体验,让我们看下它们是如何工作的。

举个例子,假设我们有一个根据狗的品类返回不同报价的函数。使用if/else语句,它会像这样:

function getDogQuote(breed) {
    if (breed.toLowerCase() === 'akita') {
        return 'Akitas do speak, but only ti those who know how ti listen'
    } else if (breed.toLowerCase() === 'beagle') {
        return 'Life id better with a Beagle'
    } else if (breed.toLowerCase() === 'dachshund') {
        return 'Why do dachshunds waer their ears inside out?'
    } else if (breed.toLowerCase() === 'golden retirever') {
        return 'The face of a Golden Retriever feeles like home'
    } else if (breed.toLowerCase() === 'pug') {
        return 'The puggle is real'
    }
    return 'Quote not found'
}

这看起来不太友好,不仅不方便阅读,而且在每条语句中还重复写了toLowerCase()

我们可以在函数的开始将品种转化为小写并赋值给一个变量来避免重复声明,或者使用switch语句,如下所示:

function getDogQuote(breed) {
    switch(breed.toLowerCase()) {
        case 'akita':
            return 'Akitas do speak, but only ti those who know how ti listen'
        case 'beagle':
            return 'Life id better with a Beagle'
        case 'dachshund':
            return 'Why do dachshunds waer their ears inside out?'
        case 'golden retirever':
            return 'The face of a Golden Retriever feeles like home'
        case 'pug':
            return 'The puggle is real'
        default:
            return 'Quote not found'
    }
}

现在我们只调用了一次toLowerCase(),但是阅读起来仍然感觉不太好。switch语句也容易出错。在这个例子中,我们只是返回了一个值,但是当你有更复杂的功能时,它也很容易遗漏break语句并引入bug

另一种选择 你可以使用一个对象以一种更简洁的方式去实现与上面相同的功能。让我们看一下例子:

function getDogQuote(breed) {
    const breeds = {
        akita: 'Akitas do speak, but only ti those who know how ti listen',
        beagle: 'Life id better with a Beagle',
        dachshund: 'Why do dachshunds waer their ears inside out?',
        'golden retirever': 'The face of a Golden Retriever feeles like home',
        pug: 'The puggle is real',
    }
    return breeds[breed.toLowerCase()] ?? 'Quote not found'
}

我们有一个对象,其中key作为条件,value作为返回值。然后我们使用中括号符号从传入的breed中选择正确的对象值。

第10行的最后一部分(?? 'Quote not found')使用nullish coalescing(空值合并)去分配一个默认的返回值。这意味着如果breeds[breed.toLowerCase()]的值是null或者undefined(但不是false或者0),那么将会返回默认字符串"Quote not found"。这很重要,因为我们可能会合理的希望从条件中返回false或0。例如:

function stringToBool(str) {
    const boolStrings = {
        "true": true,
        "false:" false
    }
    return boolStrings[str] ?? 'String in not boolean value'
}

这是一个很造作的示例,但希望它能说明空值运算符是如何帮助避免引入bug。

更复杂的逻辑

有时你可能需要在你的条件中执行一些更复杂的逻辑。为了实现这一点,你可以将函数作为value值传递给你的对象作为key并去执行响应:

function calculate(num1, num2, action) {
    const actions = {
        add: (a, b) = > a + b,
        subtract: (a, b) => a - b,
        multiply: (a, b) => a * b,
        divide: (a,b ) = > a / b
    }
    return actions[action]?.(num1, num2) ?? 'Calculation is not recognised'
}

我们可以选择我们想要执行的运算去执行响应,传递两个数字。你可以使用optional chaining(可选链式操作运算符) (?.在JavaScript中,是ES2020引入的一个新特性)只有返回的响应是defined时才会被执行,否则返回执行结果。

总结

编写条件语句总是有个人想法,不同的情况下需要使用不同的方法。然而,我发现当我有几个条件要检查时,对象字面量是最易阅读和维护的方式。

我很愿意听听你的想法,如果你有不同于以上列出的方法