前端提高代码质量-提升代码的可维护性

news2024/9/29 23:35:41
         
        代码质量是一个非常重要的概念,它决定了代码的可读性、可维护性、可扩展性和稳定性。在前端开发中,提升代码质量可以帮助我们减少错误、提高开发效率、降低维护成本,甚至可以提高用户体验。

在必要的地方加注释

        良好的注释可以帮助开发人员理解代码的逻辑、功能和实现方式,减少维护成本,提高代码质量和可维护性。

以下是一些前端代码注释的最佳实践:

  1. 注释清晰明了:注释应该简洁明了,用简单易懂的语言解释代码的逻辑和功能。避免过度使用注释,以免使代码变得冗余和难以阅读;
  2. 声明代码的意图,准确地描述函数的行为
  3. 对参数和返回值注释,入参代表什么,出参代表什么
  4. 用输入/输出的例子来说明特别的情况;
  5. 当代码还未完成时可以使用 todo 注释来注释;
  6. 使用统一的风格;

可以在vscode的插件市场,下载koroFileHeader 进行安装,可以一键生成注释格式。

统一的代码风格

        统一的前端代码风格规范可以使前端开发更加高效和易于维护。通过遵循一致的缩进和空格、行宽限制、语句结束符、语句块、命名规则、注释、文件命名、模块化和组件化等规范,可以使前端开发更加规范化、易于阅读和维护。同时,使用代码质量检查工具(如ESLint)也可以帮助团队发现和修复代码中的问题,提高代码质量。

以下是一些统一前端代码风格规范的最佳实践:

  1. 命名规范:使用有意义的变量和函数命名,遵循驼峰命名法或下划线命名法,以便于阅读和理解代码。

一般常见的命名规范如下:

  • 变量:小驼峰,使用有意义的英文命名如newsDetail
  • 函数:小驼峰,应该采用动词+名词的形式,如getNewsDetail
  • 类名:大驼峰,如EventBus
  • 常量:大写+下划线分割,如NEWS_STATUS
  • 目录:小写+中划线分割,如file-name
  • 文件:小写+中划线分割,如 event-bus.js,团队内部统一即可
  • 组件:组件名应该始终使用首字母大写的驼峰命名法
  1. 代码缩进:使用一致的代码缩进,通常是两个或四个空格,以提高代码的可读性。
  2. 行宽:限制代码行的长度,通常不超过80个字符。
  3. 括号位置:统一括号的位置,例如将所有括号放在行首还是行尾。
  4. 字符串引号使用单引号
  5. 循环判断不能超过三层

函数篇

        在编程中,函数是我们进行模块化、复用代码的重要工具。保持函数的整洁和可读性对于代码的可维护性和可扩展性至关重要。以下是一些关于如何保持函数整洁的最佳实践:

  1. 函数应该短小精悍:一个函数应该只做一件事,并且这件事应该在函数名中明确表达出来。如果一个函数开始变得过于复杂或过长(一般来说,不超过80行),那么可能就是时候考虑将其分解为更小的函数了。
  2. 避免重复:避免在多个函数中重复相同的代码。如果你发现自己在多个地方重复相同的代码,那么可能就应该将那部分代码提取出来,创建一个新的函数。
  3. 使用描述性的名称:函数的名称应该清楚地描述函数的功能。名称应该简洁明了,不要使用缩写,除非这个缩写是广泛使用的。
  4. 参数列表应该简洁:参数列表不应该过长。如果参数列表过长,那么可能就是时候考虑将某些参数封装到对象中,或者尝试使用其他设计模式来简化接口。
  5. 尽量减少全局变量的使用:全局变量可能会使得代码难以理解和维护。如果可能的话,尽量使用局部变量。
  6. 注释要恰当:注释应该是代码的补充,而不是替代。如果代码本身已经足够清晰,那么可能就不需要注释。在复杂的代码段前加上注释可以帮助阅读者理解代码的目的和工作方式。
  7. 函数应该是“纯”的:纯函数是一种函数,给定相同的输入,总是返回相同的输出,并且没有副作用。这种类型的函数通常更容易测试和理解。
  8. 错误处理:每个函数都应该能够处理错误,而不是让错误传播到调用堆栈的顶部。每个函数都应该有一个明确定义的错误处理策略。

符合阅读习惯

        写代码也是一个表达的过程,虽然表现形式不同,但是如果我们能够采用符合人类自然语言习惯的表达习惯来写代码,对阅读代码的人理解我们的代码是很有帮助的。

条件语句中的正负逻辑

在判断一些正负逻辑的时候,建议使用if(result)而不是if(!result)。

if/else语句块的顺序

        在写if/else语句的时候,可能会有很多不同的互斥情况(好多个elseif)。那么这些互斥的情况可以遵循哪些顺序呢?

  • 先处理掉简单的情况,后处理复杂的情况:这样有助于阅读代码的人循序渐进地地理解你的逻辑,而不是一开始就吃掉一个胖子,耗费不少精力。
  • 先处理特殊或者可疑的情况,后处理正常的情况:这样有助于阅读代码的人会马上看到当前逻辑的边界条件以及需要注意的地方。

使用return提前返回

        在一个函数或是方法里,可能有一些情况是比较特殊或者极端的,对结果的产生影响很大(甚至是终止继续进行)。如果存在这些情况,我们应该把他们写在前面,用return来提前返回(或者返回需要返回的返回值)。

这样做的好处是可以减少if/else语句的嵌套,也可以明确体现出:“哪些情况是引起异常的”。

以字面常量取代魔法数

        对于魔法数,应该用一个枚举对象或一个常量来赋予其可见的意义。这样,你在用到的时候,就能够明确的知道它代表的是什么意思

而且,当需求变化的时候,只需要改变一个地方即

const LOGIN_SUCCESS = '3756'; // 为业务常量命个名,看起来就非常清晰易读
if (res.code === LOGIN_SUCCESS) {
    // todos
}

简化逻辑

使用函数或者方法

        将复杂的逻辑块封装到单独的函数或者方法中。这不仅可以使你的主程序更加简洁,还可以使你的代码更加模块化,易于维护和测试。

//	not-recommended ❌
// 下面这个if里面的判断条件,需要花一番精力才能知道作者要表达的是什么;

let getPrice = function( price ){
    let date = new Date();
    if ( date.getMonth() >= 6 && date.getMonth() <= 9 ){   // 夏天
        return price * 0.8;
    }
    return price;
};

//	recommended ✅
// 提炼成单独的函数就能做到一目了然了;
let isSummer = function(){
    let date = new Date();
    return date.getMonth() >= 6 && date.getMonth() <= 9;
};
let getPrice = function( price ){
    if (isSummer() ){    // 夏天
        return price * 0.8;
    }
    return price;
};

减少if...else面条代码

        为完成一个功能每个程序员都会有不同的算法或者说写法,通常来说越清晰的算法可维护性越高。当发现做一件事可以有更清晰的方式,你就就应该用比较清晰的方式取代复杂的方式。

function foundPerson(people) {
  for(let i = 0; i < people.length; i++) {
    if (people[i] === "Don") {
      return "Don";
    }
    if (people[i] === "John") {
      return "John";
    }
    if (people[i] === "Kent") {
      return "Kent";
    }
  }
  return "";
}

我们其实并不需要这些条件语句:

function foundPerson(people) {
  const candidates = ["Don", "John", "Kent"];
  return people.find(p => candidates.includes(p)) || '';
}

switch代替多个if else

function commandHandle(command){
    if(command === 'install'){
        install()
    }else if(command === 'start'){
        start()
    }else if(command === 'restart'){
      restart()
    }else{
        showToast('未知命令')
    }
}

switch比较适合这种判断条件比较单一的情况,如判断是否等于某个字符串或者数字,如果if条件存在3个及以上,使用switch相对来说结构更加清晰。

function commandHandle(command){
    switch (command){
      case 'install':
          install();
          break;
      case 'start':
          start();
          break;
      case 'restart':
          restart();
          break
      default:{
        showToast('未知命令')
      }
    }
}

还可以进行更进一步的优化,通过一个map来指定每个命令对应的动作。

可以利用策略模式来做进一层的优化

function commandHandle(command) {
  let commandHandleMap = {
    install,
    start,
    restart,
    default: () => showToast('未知命令')
  }
  let handle = commandHandleMap[command] || commandHandleMap['default']
  handle()
}


​​​​​​​卫语句取代嵌套条件表达式

如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为“卫语句

function getPayAmount() {
  let result;
  if (isDead)
    result = deadAmount();
  else {
    if (isSeparated)
      result = separatedAmount();
    else {
      if (isRetired)
        result = retiredAmount();
      else
        result = normalPayAmount();
    }
  }
  return result;
}   
使用卫语句可以大大减少嵌套语句的数量,增强可读性:
function getPayAmount() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retiredAmount();
  
  return normalPayAmount();
}​​​​​​​

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

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

相关文章

使用RKDevTool将update.img完整镜像进行解包,得到单独分区的镜像

(1)使用开发工具高级功能的解包 导入xx.img,然后点击解包(2)在Output/Android/Image得到想要的image

zotero通过DOI快速导入文献

之前我经常采用两种方式导入文献&#xff1a; &#xff08;1&#xff09;下载PDF&#xff0c;然后拖入zotero 这种方法比较费时间&#xff0c;有些文献无法下载pdf &#xff08;2&#xff09;通过google scholar检索文献&#xff0c;然后点击引用——EndNote&#xff0c;chorme…

HCQ1-1300-D故障笔记

常用查错网址&#xff1a; SMC_ERROR (ENUM) 删除 Web

socket套接字——TCP协议

目录 一、TCP协议相关函数 1.socket、bind函数 2.listen函数 3.accept函数 4.connect函数 二、实现TCP通信 1.服务端实现 &#xff08;1&#xff09;服务端类 &#xff08;2&#xff09;日志小组件 &#xff08;3&#xff09;初始化服务端 &#xff08;4&#xff09…

etcd的安装和使用

安装及启动 在Mac上&#xff0c;推荐使用brew安装 brew install etcd 可以使用etcd启动服务&#xff0c;但更推荐使用 brew services 来管理使用brew安装的应用~ # 启动某个应用&#xff0c;这里用 etcd 做演示brew services start etcd# 停止某个应用brew services stop etcd#…

Hive的分区和分桶

目录 ​编辑 一、Hive分区 1.1 分区产生的背景 1.2 动态分区 1.2.1 hive的动态分区介绍 1.2.2 动态分区配置 1.2.2.1 动态分区开启 1.2.2.2 动态分区模式 1.2.2.3 一个mr节点上&#xff0c;设置动态分区的最大数量 1.2.2.4 所有mr节点上&#xff0c;设置所有动态分区…

linux安装redis超级详细教程

redis源码安装 安装gcc redis是C语言编写的&#xff0c;所以我们需要先在Linux上安装和升级&#xff0c;C语言的编译环境。 #安装gcc yum install -y gcc-c autoconf automake#centos7 默认的 gcc 默认是4.8.5,版本小于 5.3 无法编译,需要先安装gcc新版才能编译 gcc -v#升级…

rv1126-rv1109-环境搭建-全部编译的方法

主要参考:Rockchip_Developer_Guide_Linux_Software_CN.pdf / SDK-Rockchip_RV1126_RV1109_Quick_Start_Linux_CN.pdf 找对文档事半功倍!为什么这么说,因为没找对绕了路!别笑! //解压源码,基础略过 tar xvf rv1126_rv1109_linux_v3.0.2_20230724.tgz -C rv1126_rv1109 cd rv1…

【Axure高保真原型】动态控制不透明度

今天和大家分享动态控制不透明度的原型模板&#xff0c;我们可以滑块左右拖动或者点击滑条的某个位置&#xff0c;从而控制图片上方遮罩的不透明度……具体效果可以打开下方原型地址体验或者点击下方视频观看 【原型效果】 【Axure高保真原型】动态控制不透明度 【原型预览及下…

No thread-bound request found 错误以及解决方案

异常信息&#xff1a; cause: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually o…

一起学数据结构(7)——树及二叉树的基本概念及存储

前面的关于数据结构的文章中&#xff0c;介绍了顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列等数据结构。对于以上数据结构&#xff0c;均是一对一的关系。本篇文章将对于一对多的数据结构——树进行解析。 目录 1. 树的定义及基本概念&#xff1a; 1.1 树的定义&a…

结合el-tooltip,实现内容过长省略,移上显示全部

在系统中&#xff0c;内容过长需要省略&#xff0c;鼠标移上显示全部&#xff0c;这个是常用的功能&#xff0c;也有很多方案解决这种。 单行内容超出处理 常用的css方案&#xff1a; .ellipsis {overflow: hidden;white-space: nowrap;text-overflow: ellipsis; } 该样式在…

基于Android系统英语学习助手APP设计开发

一、 设计思路 1.1设计目标 1.2设计思路 1.3设计内容 1.3.1界面设计 1.3.2功能模块设计 1.3.3功能流程图 1.3.4数据库设计&#xff08;如果没有数据库这部分删除&#xff09; 1.4工具设备要求 1.5技术方案 二、设计过程与说明 2.1技术路线 2.2实现方案 2.3实现原理…

C#复习:面向对象基本概念

C#复习&#xff1a;面向对象基本概念 前言什么是面向对象类&#xff0c;名称空间的介绍 如何导入类库DLL引用(黑盒引用)项目引用(白盒引用)NuGet介绍 依赖关系C#的分装(个人理解) 前言 关于我C#的博客是根据刘铁猛老师的C#入门课程为基础写的&#xff0c;可以配合刘铁猛老师的…

.bat批处理命令处理文件

批处理命令处理文件找到上级目录&#xff0c;并删除文件与文件夹 参考资料&#xff1a; [BAT] 如何获取bat的上一级目录、上两级目录..._bat 上层目录_Risun_Lee的博客-CSDN博客echo offset currPath%~dp0set parentPathset parentparentPath:beginfor /f "tokens1,* de…

solidworks导出文本能打开的stl文件

几种以文本格式&#xff08;ASCII&#xff09;导出stl的设置 1.solidworks导出时需要在选项里设置导出格式为ASCII&#xff0c;当选择以二进制格式导出时&#xff0c;打开会乱码&#xff1b; 2.CAD直接导出的是以二进制形式导出的&#xff0c;导出后也无法使用文本打开&#xf…

NVIDIA DALI学习:数据加载

DALI的工作流&#xff0c; 如下图&#xff1a; 读取数据图像解码和变换&#xff0c;可以放到GPU上进行&#xff0c;也是加速的关键生成处理好的数据&#xff0c; 导出给计算引擎 测试用例 import ctypesimport numpy as np import nvidia.dali.fn as fn import nvidia.dali…

关于Godot动态生成节点的细节

var dy_btn Button.new()add_child(dy_btn)print(get_child(0).name) 此时获取的名词会带有动态类型&#xff0c;如果这个时候想通过特定的节点名词来获取节点是不行的 此时需要补充类似 dy_btn.name "a" 的代码&#xff0c;然后就能按照节点名词获取节点了

Java下打印九九乘法表

这个算法是基于打直角三角型演变而来&#xff0c;代码如下&#xff1a; public class MyWork {public static void main(String[] args) {for (int i 1; i < 10; i) {for (int j 1; j < i; j) {System.out.print(j "x" i "" i*j "\t&qu…