3

JavaScript 代码逻辑判断的优化

 3 years ago
source link: https://my.oschina.net/wangzhijie/blog/5072287
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

我们日常使用到的逻辑判断语句有 if...else...switch...case...do...while...等。

在简单场景下,我们可能对这些语法的性能没有什么感觉,但当遇到复杂的业务场景时,如果处理不善,就会出现大量的逻辑嵌套,可读性差并且难以扩展。

千里之行始于足下,编写高可维护性和高质量的代码,我们就需要从细节处入手,我们今天主要讨论 JavaScript 中如何优化逻辑判断代码。

R54dad6197ce9d42a7fd8c7b23e4b5a18

嵌套层级优化

function supply(fruit, quantity) {
    const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
    // 条件 1: 水果存在
    if (fruit) {
        // 条件 2: 属于红色水果
        if (redFruits.includes(fruit)) {
            console.log('红色水果');
            // 条件 3: 水果数量大于 10 个
            if (quantity > 10) {
                console.log('数量大于 10 个');
            }
        }
    } else {
        throw new Error('没有水果啦!');
    }
}

通过上面这个例子,我们可以看到:判断流程中规中矩,符合现实世界的映射。但是,因代码层层嵌套,导致阅读和维护都存在困难。

如果传入了 fruit 参数,则每次执行都至少需要经过两步 if 判断,在性能上也存在问题。

我们来对上面的代码进行一下优化处理:

function supply(fruit, quantity) {
    const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
    if (!fruit) throw new Error('没有水果啦');     // 条件 1: 当 fruit 无效时,提前处理错误
    if (!redFruits.includes(fruit)) return; // 条件 2: 当不是红色水果时,提前 return

    console.log('红色水果');

    // 条件 3: 水果数量大于 10 个
    if (quantity > 10) {
        console.log('数量大于 10 个');
    }
}

这里主要对嵌套层级做了优化,提前终止掉了不符合的条件,将三层嵌套减少到了一层,简化了代码结果结构,增强了可阅读性。

多条件分支的优化

相信我们很多人对下面这种代码不陌生吧?(想想刚开始写代码那会啊)

function pick(color) {
    // 根据颜色选择水果
    if (color === 'red') {
        return ['apple', 'strawberry'];
    } else if (color === 'yellow') {
        return ['banana', 'pineapple'];
    } else if (color === 'purple') {
        return ['grape', 'plum'];
    } else {
        return [];
    }
}

我们需要知道一点原则:if else 更适合于条件区间判断,而 switch case 更适合于具体枚举值的分支判断。

我们使用 switch...case...进行一下改写:

function pick(color) {
    // 根据颜色选择水果
    switch (color) {
        case 'red':
            return ['apple', 'strawberry'];
        case 'yellow':
            return ['banana', 'pineapple'];
        case 'purple':
            return ['grape', 'plum'];
        default:
            return [];
    }
}

switch...case... 优化之后的代码看上去格式整齐,思路很清晰,但还是很冗长。继续优化:

  • 借助 Object 的 {key: value} 结构,我们可以在 Object 中枚举所有的情况,然后将 key 作为索引,直接通过 Object.key 或者 Object[key] 来获取内容:
const fruitColor = {
    red: ['apple', 'strawberry'],
    yellow: ['banana', 'pineapple'],
    purple: ['grape', 'plum'],
}
function pick(color) {
    return fruitColor[color] || [];
}
  • 使用 Map 数据结构,真正的(key, value) 键值对结构:
const fruitColor = new Map()
    .set('red', ['apple', 'strawberry'])
    .set('yellow', ['banana', 'pineapple'])
    .set('purple', ['grape', 'plum']);

function pick(color) {
    return fruitColor.get(color) || [];
}

优化之后,代码更简洁、更容易扩展。

为了更好的可读性,还可以通过更加语义化的方式定义对象,然后使用 Array.filter 达到同样的效果:

const fruits = [
    {name: 'apple', color: 'red'},
    {name: 'strawberry', color: 'red'},
    {name: 'banana', color: 'yellow'},
    {name: 'pineapple', color: 'yellow'},
    {name: 'grape', color: 'purple'},
    {name: 'plum', color: 'purple'}
];

function pick(color) {
    return fruits.filter(f => f.color == color);
}

上面使用的例子和手段都比较初级,但是其中的思想却值得我们细品,希望大家能够有所收获!

Rae9e3dd90e39afb101b1ea3b1c9d373b

学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

大家好!我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK