JS代码优化——逻辑判断

news2024/11/30 14:47:14

文章目录

    • JavaScript 语法篇
      • 嵌套层级优化
      • 多条件分支的优化处理
      • 使用数组新特性简化逻辑判断
        • **多条件判断**
        • **判断数组中是否所有项都满足某条件**
        • **判断数组中是否有某一项满足条件**
      • **函数默认值**
        • 使用默认参数
        • 使用解构与默认参数
        • 复杂数据解构
      • 策略模式优化分支逻辑处理

JavaScript 语法篇

嵌套层级优化

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('没有水果啦!');
  }
}

分析上面的条件判断,存在三层 if 条件嵌套。

如果提前 return 掉无效条件,将 if else的多重嵌套层次减少到一层,更容易理解和维护。

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 个');
  }
}

多条件分支的优化处理

当需要枚举值处理不同的业务分支逻辑时, 第一反应是写下 if else ?我们来看一下:

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 分支太多
  • 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);
}

使用数组新特性简化逻辑判断

巧妙的利用 ES6 中提供的数组新特性,也可以让我们更轻松的处理逻辑判断。

多条件判断

编码时遇到多个判断条件时,本能的写下下面的代码(其实也是最能表达业务逻辑的面向过程编码)。

function judge(fruit) {
  if (fruit === 'apple' || fruit === 'strawberry' || fruit === 'cherry' || fruit === 'cranberries' ) {
    console.log('red');
  }
}

但是当 type 未来到 10 种甚至更多时, 我们只能继续添加 || 来维护代码么 ?

试试 Array.includes ~

// 将判断条件抽取成一个数组
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
function judge(type) {
  if (redFruits.includes(fruit)) {
    console.log('red');
  }
}

判断数组中是否所有项都满足某条件

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

function match() {
  let isAllRed = true;

  // 判断条件:所有的水果都必须是红色
  for (let f of fruits) {
    if (!isAllRed) break;
    isAllRed = (f.color === 'red');
  }

  console.log(isAllRed); // false
}

上面的实现中,主要是为了处理数组中的所有项都符合条件。

使用 Array.every 可以很容的实现这个逻辑:

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

function match() {
  // 条件:所有水果都必须是红色
  const isAllRed = fruits.every(f => f.color == 'red');

  console.log(isAllRed); // false
}

判断数组中是否有某一项满足条件

Array.some ,它主要处理的场景是判断数组中是否有一项满足条件。

如果想知道是否有红色水果,可以直接使用 Array.some 方法:

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

// 条件:是否有红色水果 
const isAnyRed = fruits.some(f => f.color == 'red');

还有许多其他数组新特性,比如 Array.find、Array.slice、Array.findIndex、Array.reduce、Array.splice 等,在实际场景中可以根据需要选择使用。

函数默认值

使用默认参数

const buyFruit = (fruit,amount) => {
  if(!fruit){
    return
  }
  amount = amount || 1;
  console.log(amount)
}

我们经常需要处理函数内部的一些参数默认值,上面的代码大家都不陌生,使用函数的默认参数,可以很好的帮助处理这种场景。

const buyFruit = (fruit,amount = 1) => {
  if(!fruit){
    return
  }
  console.log(amount,'amount')
}

我们可以通过 Babel 的转译来看一下默认参数是如何实现的。

img

从上面的转译结果可以发现,只有参数为 undefined 时才会使用默认参数。

测试的执行结果如下:

buyFruit('apple','');  // amount
buyFruit('apple',null);  //null amount
buyFruit('apple');  //1 amount

所以使用默认参数的情况下,我们需要注意的是默认参数 amount=1 并不等同于 amount || 1

使用解构与默认参数

当函数参数是对象时,我们可以使用解构结合默认参数来简化逻辑。

Before:

const buyFruit = (fruit,amount) => {
    fruit = fruit || {};
    if(!fruit.name || !fruit.price){
        return;
    }
    ...
  amount = amount || 1;
  console.log(amount)
}

After:

const buyFruit = ({ name, price }={},amount) => {
  if(!name || !prices){
      return;
  }
  console.log(amount)
}

复杂数据解构

当处理比较简的对象时,解构与默认参数的配合是非常好的,但在一些复杂的场景中,我们面临的可能是更复杂的结构。

const oneComplexObj = {
    firstLevel:{
        secondLevel:[{
            name: "",
            price: ""
        }]
    }
}

这个时候如果再通过解构去获取对象里的值。

const {
  firstLevel:{
    secondLevel: [{name, price]=[]
  }={}
} = oneComplexObj;              

可读性就会比较差,而且需要考虑多层解构的默认值以及数据异常情况。

这种情况下,如果项目中使用 lodash 库,可以使用其中的 lodash/get 方法。

import lodashGet from 'lodash/get';

const { name, price} = lodashGet(oneComplexObj,'firstLevel.secondLevel[0]',{});

策略模式优化分支逻辑处理

策略模式:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

使用场景:策略模式属于对象行为模式,当遇到具有相同行为接口、行为内部不同逻辑实现的实例对象时,可以采用策略模式;或者是一组对象可以根据需要动态的选择几种行为中的某一种时,也可以采用策略模式;这里以第二种情况作为示例:

Before:

const TYPE = {
  JUICE:'juice',
  SALAD:'salad',
  JAM:'jam'
}
function enjoy({type = TYPE.JUICE,fruits}){
  if(!fruits || !fruits.length) {
    console.log('请先采购水果!');
    return;
  }
  if(type === TYPE.JUICE) {
    console.log('榨果汁中...');
    return '果汁';
  }
  if(type === TYPE.SALAD) {
    console.log('做沙拉中...');
    return '拉沙';
  }
  if(type === TYPE.JAM) {
    console.log('做果酱中...');
    return '果酱';
  }
  return;
}

enjoy({type:'juice',fruits});

使用思路:定义策略对象封装不同行为、提供策略选择接口,在不同的规则时调用相应的行为。

After:

const TYPE = {
  JUICE:'juice',
  SALAD:'salad',
  JAM:'jam'
}

const strategies = {
  [TYPE.JUICE]: function(fruits){
    console.log('榨果汁中...');
    return '果汁';
  },
  [TYPE.SALAD]:function(fruits){
    console.log('做沙拉中...');
    return '沙拉';
  },
  [TYPE.JAM]:function(fruits){
    console.log('做果酱中...');
    return '果酱';
  },
}

function enjoy({type = TYPE.JUICE,fruits}) {
  if(!type) {
    console.log('请直接享用!');
    return;
  }
  if(!fruits || !fruits.length) {
    console.log('请先采购水果!');
    return;
  }
  return strategies[type](fruits);
}

enjoy({type: 'juice',fruits});

sole.log(‘做沙拉中…’);
return ‘沙拉’;
},
[TYPE.JAM]:function(fruits){
console.log(‘做果酱中…’);
return ‘果酱’;
},
}

function enjoy({type = TYPE.JUICE,fruits}) {
if(!type) {
console.log(‘请直接享用!’);
return;
}
if(!fruits || !fruits.length) {
console.log(‘请先采购水果!’);
return;
}
return strategiestype;
}

enjoy({type: ‘juice’,fruits});


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/527759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mars3d实现加载gif动图

官网有相关示例参考:功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 方式1: // [终点]绘制台风当前位置gif点 const gifGraphic new mars3d.graphic.DivGraphic({ position: [endItem.lon, e…

【人力资源管理】第3集 免费开源ERP: Odoo 16 hr_holidays管理员工休假和缺勤 构建一体化企业人力资源管理

文章目录 前言一、管理员工休假二、批准或者拒绝休假申请三 、简单报表工具四 、使用功能1.管理休假申请2.报告 总结 前言 管理员工休假和缺勤。 一、管理员工休假 跟踪所有员工的假期 跟踪每位员工的休假天数。员工输入请求,经理对请求进行审批和验证&#xff0…

MYSQL-数据库管理.3(用户管理及用户权限)

一、关系型数据库 数据结构 二维表格 库 -> 表 -> 列(字段):用来描述对象的一个属性 行(记录):用来描述一个对象的信息 二、非关系型数…

能成事的表达笔记

为什么需要好的沟通? 一.让自己舒服 二.让别人乐意 愿意听听得懂听完愿意配合你 共赢 沟通是思维和视角的改变 向上沟通 (领导,客户) 是最高效的职场成长路径 痛点: 出于恐惧而挖掘不到真实的需求 一味听从权威…

spring项目里的大事务优化

编程型事务更加灵活 声明式事务只需要加在方法头加Transactional注解即可开启事务,但是还是不太灵活,意味着整个方法所进行对数据库操作都要加进事务,当然一次查询也要进入事务,这并不是我们想要的,我们在update、ins…

电容笔和触控笔哪个好用?2023平价好用的电容笔测评

其实,许多产品各有特色,有的注重外观,而有的注重功能。ipad上的那支笔也是如此的。所以,购买电容笔的时候,必须对电容笔有充分的了解。在选购前,必须了解各种类型的电容笔,以决定选购何种电容笔…

ASEMI代理LTC3309AEV#TRMPBF原装ADI车规级LTC3309AEV#TRMPBF

编辑:ll ASEMI代理LTC3309AEV#TRMPBF原装ADI车规级LTC3309AEV#TRMPBF 型号:LTC3309AEV#TRMPBF 品牌:ADI /亚德诺 封装:LQFN-12 批号:2023 安装类型:表面贴装型 引脚数量:12 工作温度:-4…

数字演播厅全新上线,让您的业务展示事半功倍

向客户汇报时还在手忙脚乱找应用? 给领导汇报时还在尴尬的等待应用漫长的加载? 还在因为没有合适的控制设备而施展不开拳脚? 为帮助广大易知微用户提升演示汇报效果,易知微平台上线了「数字演播厅」功能,该功能专注…

22. Unity - 3D游戏开发小计01 --- 修复动画BUG、更改环境光照、导航网格、相机跟随、场景渲染后期处理

1. 导入玩家角色模型 素材来自于unity官网:3D Beginner:Tutorial Resources 在3D游戏开发中,三维物体模型一般会有团队内的其它成员提供,包括模型本身和动画文件等。我们需要做的是将这些素材进行组合并使用代码进行控制。 若对模型添加动画文件后,当运行时可能会发现模型…

OPPO舍弃芯片研发,让人想起欧洲芯片,国产芯片会从此溃败么?

OPPO一瞬间舍弃芯片研发,对国产芯片造成的影响无疑是非常大的,甚至可能导致国产芯片的研发由此溃败,这可以从当年欧洲的芯片业务衰败作为前车之鉴。 GSM称霸2G时代,也让欧洲手机和欧洲芯片企业取得优势,当年爱立信手机…

小红书文案怎么写才能吸引用户,品牌写文技巧

在小红书平台,文案是笔记非常重要的一环,那么文案怎么写才能吸引人呢?下面就让我们来聊一聊小红书文案写作的一些技巧,希望可以对大家有所帮助。 一、 标题 一个好的标题是非常重要的,这相当于是一篇笔记的门面,决定着…

什么是 Java 中的 AOP(面向切面编程)?如何使用它来实现横切关注点?

AOP(Aspect-oriented programming,面向切面编程),是一种编程思想和技术,旨在将横切关注点和主业务逻辑分离,使得系统更容易扩展和维护。在 Java 中,AOP 主要通过代理模式和动态字节码生成实现。…

不限次数的chatGPT

不说废话直接看方法: 不用翻墙,开干 第一步:打开电脑的Edge浏览器,就是windows系统的默认浏览器,搜索wetab,点击如下的官方链接就会进入安装插件界面 第二步:点击chat AI就会弹出这个弹窗&…

如何将 Docker 镜像大小从 1.43 GB 减少到 22.4 MB

如果你正在从事 Web 开发,那么你可能已经了解过容器化的概念以及它的优点。 但是,当使用 Docker 时,镜像大小是一个很大的问题。仅仅是从 create-react-app 中得到的样板项目就通常超过 1.43 GB。 今天我们将会容器化一个 ReactJS 应用程序…

九宫格游戏-第14届蓝桥杯省赛Scratch初级组真题第5题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第134讲。 九宫格游戏,本题是2023年5月7日举行的第14届蓝桥杯省赛Scratch图形化编程初级组真题第5题&#…

渗透无回显,放弃 or 看这篇文章

渗透无回显,放弃 or 看这篇文章 1.DNSlog工具2.DNSlog回显原理3.无回显的XXE 1.DNSlog工具 如果有自己的服务器和域名,可以自建一个这样的DNSlog平台用于进行渗透数据外带,或者直接使用BugScan团队开源的工具搭建即可: Github:D…

初识kubernetes

初识kubernetes 1.应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与缺点:不能为应用程…

汽车牌照目标检测(Python代码)

1.数据集 Chinese City Parking Dataset 2.代码流程: 代码的主要流程如下: 导入所需的库和模块,包括警告过滤、数据处理、数据可视化等。 创建用于显示样本图像的子图。 从数据集中加载样本图像并显示在子图中。 提取样本图像的元数据&…

2023HAS华为分析师大会:华为认证推动数字化转型向前发展

4月19日,华为数字化人才成熟度模型正式作为TM Forum TOD (Tech Organization Design)标准文档对外发布。该模型由华为联合TMF组织、运营商客户专家学者共同研发,旨在帮助企业从组织、人才、文化维度进行评估,指导人才发展。 在2023华为分析师…

基于混沌集成决策树的电能质量复合扰动识别(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…