如何正确地使用ES6提高我们的代码质量

news2025/1/10 20:41:33

前言

相信每个前端工程师,或者了解前端的人都知道ES6。它是js的一次巨变,它为我们开发js前端项目的时候带来了许多更好的去书写代码的方式。但是很多时候我们可能都没有过度地去关注优化代码这一块内容,哪怕有也只是注意到了一些比较大众化,比较常见的东西,比如let和const、箭头函数、解构赋值……。这一篇文章将会简单直观,清晰明了地阐述ES6的一些变革和它们的真正使用方式。

1、 模板字符串

// bad
const foo = 'this is a' + example;

// good
const foo = `this is a ${example}`;

优点:对比之前能更方便地去拼接字符串,阅读性也更强一些。

2、Symbol

①唯一值

// bad
// 1. 创建的属性会被 for-in 或 Object.keys() 枚举出来
// 2. 一些库可能在将来会使用同样的方式,这会与你的代码发生冲突
if (element.isMoving) {
  smoothAnimations(element);
}
element.isMoving = true;

// good
if (element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__) {
  smoothAnimations(element);
}
element.__$jorendorff_animation_library$PLEASE_DO_NOT_USE_THIS_PROPERTY$isMoving__ = true;

// better
var isMoving = Symbol("isMoving");

...

if (element[isMoving]) {
  smoothAnimations(element);
}
element[isMoving] = true;

②魔术字符串

首先需要理解什么是魔术字符串:

魔术字符串指的是在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
魔术字符串不利于修改和维护,风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。

直接贴代码更直观:

function getResults(param{
	if(param == 'name'){
		// ...
	}
}
// 函数中赋值 'name',所以 'name' 这个字符串就是魔术字符串
getResults('name')

那如何去改善,优雅地改动我们的代码,举个栗子。

在这里插入图片描述

3、Set 和 Map

①Set可以常用到的操作:数组去重

[...new Set(array)]

②Map优化条件语句

// 根据颜色找出对应的水果

// bad
function test(color) {
  switch (color) {
    case 'red':
      return ['apple', 'strawberry'];
    case 'yellow':
      return ['banana', 'pineapple'];
    case 'purple':
      return ['grape', 'plum'];
    default:
      return [];
  }
}

// good
const fruitColor = {
  red: ['apple', 'strawberry'],
  yellow: ['banana', 'pineapple'],
  purple: ['grape', 'plum']
};

function test(color) {
  return fruitColor[color] || [];
}

// better
const fruitColor = new Map([
  ['red', ['apple', 'strawberry']],
  ['yellow', ['banana', 'pineapple']],
  ['purple', ['grape', 'plum']]
]);

对比good,better这种写法是优化了什么?

1.数据结构更清晰:Map不同于Object,它可以直接存储键值对,使得数据的表达更加清晰,避免了对象中存在原型属性和方法带来的干扰。
2.可迭代性更好:Map是一个可迭代的数据结构,所以在遍历Map时可以直接使用for…of循环或者forEach方法进行遍历,避免了使用Object.keys()等方法获取属性名的麻烦。
3.代码性能更高:Map对于大量数据的处理效率要高于对象。

4. for of

for…of 循环可以使用的范围包括:

  • 数组
  • Set
  • Map
  • 类数组对象,如 arguments 对象、DOM NodeList 对象
  • Generator 对象
  • 字符串

ES2015 引入了 for…of 循环,它结合了 forEach 的简洁性和中断循环的能力,简而言之,用for of比 forEach更好

for (const v of ['a', 'b', 'c']) {
  console.log(v);
}
// a b c

for (const [i, v] of ['a', 'b', 'c'].entries()) {
  console.log(i, v);
}
// 0 "a"
// 1 "b"
// 2 "c"

5、 Promise

Promise是解决‘先后问题’(需要先得到一个参数才能解决另一件事情的时候)的一个很好的方案。

// bad
request(url, function(err, res, body) {
    if (err) handleError(err);
    fs.writeFile('1.txt', body, function(err) {
        request(url2, function(err, res, body) {
            if (err) handleError(err)
        })
    })
});

// good
request(url)
.then(function(result) {
    return writeFileAsynv('1.txt', result)
})
.then(function(result) {
    return request(url2)
})
.catch(function(e){
    handleError(e)
});

finally,表示无论如何最后都会执行的代码。

fetch('file.json')
.then(data => data.json())
.catch(error => console.error(error))
.finally(() => console.log('finished'));

6、Async

异步解决方案之一,让代码变得更简洁,可以发挥跟promise差不多的作用。错误处理得用try……catch,async和await必须同时存在。

// 例子 8-3

// good
function fetch() {
  return (
    fetchData()
    .then(value1 => {
      return fetchMoreData(value1)
    })
    .then(value2 => {
      return fetchMoreData2(value2)
    })
  )
}

// better
async function fetch() {
  const value1 = await fetchData()
  const value2 = await fetchMoreData(value1)
  return fetchMoreData2(value2)
};

错误捕获

// 例子 8-4

// good
function fetch() {
  try {
    fetchData()
      .then(result => {
        const data = JSON.parse(result)
      })
      .catch((err) => {
        console.log(err)
      })
  } catch (err) {
    console.log(err)
  }
}

// better
async function fetch() {
  try {
    const data = JSON.parse(await fetchData())
  } catch (err) {
    console.log(err)
  }
};

promise和async看情况使用,代码更加优雅。

// bad
(async () => {
  const getList = await getList();
  const getAnotherList = await getAnotherList();
})();

// good
(async () => {
  const listPromise = getList();
  const anotherListPromise = getAnotherList();
  await listPromise;
  await anotherListPromise;
})();

// good
(async () => {
  Promise.all([getList(), getAnotherList()]).then(...);
})();

7、函数

这个不多说了,简单直接,清晰明了。

// bad
function test(quantity) {
  const q = quantity || 1;
}

// good
function test(quantity = 1) {
  ...
}

这里有解构赋值的知识点,究极蛇皮有用。 better的写法可以解决不传参会报错的问题。

doSomething({ foo: 'Hello', bar: 'Hey!', baz: 42 });

// bad
function doSomething(config) {
  const foo = config.foo !== undefined ? config.foo : 'Hi';
  const bar = config.bar !== undefined ? config.bar : 'Yo!';
  const baz = config.baz !== undefined ? config.baz : 13;
}

// good
function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 }) {
  console.log(foo)
}

dosomething(); // 这里会报错,foo没定义

// better
function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 } = {}) {
  ...
}

以上代码从这位大佬→冴羽的文章copy而来,虽然文章中很多地方只贴了代码,但是却很容易让人有一针见血的触动,不过个人还是觉得缺少一些必要的说明分析,所以我做了一点补充。

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

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

相关文章

Linux进程概念引入

文章目录 冯诺依曼体系操作系统概念设计目的定位系统调用和库函数的概念 进程概念描述进程PCBtask_struct内容分类 组织进程查看进程通过系统调用获取进程标识符通过系统调用创建进程 冯诺依曼体系 目前我们的计算机基本都是遵守冯诺依曼体系的,在冯诺依曼体系中&am…

[Kubernetes] - RabbitMQ学习

1.消息队列 消息: 在应用间传送的数据队列,先进先出 1.2. 作用 好处:解耦, 容错,削峰坏处:降低系统可用性,系统复杂度提高,一致性问题; RabbitMQ组成部分&#xff1a…

云上高校导航 导入 与 配置教程

开通 云开发 功能(首月免费,次月19.9),激活 云数据库、云存储和云函数 功能。 将 项目 文件夹下 最新版本的 文件夹下的 Cloud-based_University_Navigation 整个文件夹 复制到项目路径下(比如 D:\WeChatProjects&…

Zabbix Server Api批量添加Zabbix Agent

脚本或使用自动化工具来批量添加Zabbix Agent,从而减少手动操作和提高效率 使用API添加主机可以减少人为错误的发生。通过自动化和脚本,可以确保正确的配置被应用到每个主机上,避免了手动操作可能导致的配置错误。 使用前提条件 1、zabbix…

C919用了哪些人工智能(AI)技术?

#国产大飞机C919商业首飞#近日,C919在国人的期盼下终于迎来了首次商飞,机票已公开售卖。众所周知,C919是一款全新的、先进的大飞机,那你知道它采用了哪些新的人工智能(AI)技术吗?下面让我来为大…

[golang 微服务] 2. RPC架构介绍以及通过RPC实现微服务

一.简介 在上一节简单了解了微服务定义和优缺点之后,在使用微服务框架之前,需要首先了解一下RPC架构,通过RPC可以更形象了解微服务的工作流程 RPC的概念 RPC(Remote Procedure Call Protocol),是 远程过程调用的缩写,通俗的说就是…

【提示学习】HPT: Hierarchy-aware Prompt Tuning for Hierarchical Text Classification

论文信息 名称内容论文标题HPT: Hierarchy-aware Prompt Tuning for Hierarchical Text Classification论文地址https://arxiv.org/abs/2204.13413研究领域NLP, 文本分类, 提示学习, 层级标签文本分类提出模型HPT(Hierarchy-aware Prompt Tuning)来源EMNLP 2022源码https://gi…

SpringBoot AOP切面编程 使用案例

参考资料 Springboot AOP实现指定敏感字段数据加密 (数据加密篇 二)【SpringBoot-3】切面AOP实现权限校验:实例演示与注解全解【小家Spring】Spring AOP中Pointcut切入点表达式最全面使用介绍AOP编程过程中的Signature接口 本篇文章核心思想…

(详解)vue中实现主题切换的三种方式

目录 一、背景 二、实现思路 方法1:定义全局的CSS变量 方法2:切换已定义好的css文件 方法3:切换顶级CSS类名 (需使用css处理器,如sass、less等) 一、背景 在我们开发中我们会遇到像是需要切换程序风格、主题切换啦这种应用场景。 参考大佬…

经典智能合约案例之发红包

经典智能合约案例:发红包 角色分析:发红包的人和抢红包的人 功能分析: 发红包:发红包的功能,可以借助构造函数实现,核心是将ether打入合约; 抢红包:抢红包的功能,抢成…

Flume系列:案例-Flume 聚合拓扑(常见的日志收集结构)

目录 Apache Hadoop生态-目录汇总-持续更新 1:案例需求-实现聚合拓扑结构 3:实现步骤: 2.1:实现flume1.conf - sink端口4141 2.2:实现flume2.conf- sink端口4141 2.3:实现flume3.conf - 监听端口4141 …

32 KVM管理系统资源-管理虚拟内存热插

文章目录 32 KVM管理系统资源-管理虚拟内存热插32.1 概述32.2 约束限制32.3 操作步骤32.3.1 配置虚拟机XML32.3.2 热插并上线内存 32 KVM管理系统资源-管理虚拟内存热插 32.1 概述 在虚拟化场景下,虚拟机的内存、CPU、外部设备都是软件模拟呈现的,因此…

深度学习进阶篇-国内预训练模型[5]:ERINE、ERNIE 3.0、ERNIE-的设计思路、模型结构、应用场景等详解

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

旧键盘打字 两数之和

💕"不要因为别人的成功而感到沮丧,你的时机会来,只要你继续努力、坚持不懈。"💕 🐼作者:不能再留遗憾了🐼 🎆专栏:Java学习🎆 🚗本文章主要内容:使用哈希表的思…

2023年江苏省中职网络安全Web渗透测试解析(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.访问地址http://靶机IP/web1,分析页面内容,获取flag值,Flag格式为flag{xxx}; 2.访问地址http://靶机IP/web2,访问登录页面。用户user01的密码为1-1000以内的数,获取用户user01的密码,将密码作为Flag进行提交,Flag格式为…

Java数据结构之第十四章、泛型进阶

补充复杂示例&#xff1a; public class MyArray<E extends Comparable<E>> { ... } 表明E必须是实现了Comparable接口的 泛型基础内容 目录 一、通配符 二、通配符上界 三、通配符下界 一、通配符 ? 用于在泛型的使用&#xff0c;即为通配符 示例&#xf…

如何使用 Python Nornir 实现基于 CLI 的网络自动化?

在现代网络环境中&#xff0c;网络自动化已成为管理和配置网络设备的重要工具。Python Nornir 是一个强大的自动化框架&#xff0c;它提供了一个简单而灵活的方式来执行网络自动化任务。本文将详细介绍如何使用 Python Nornir 实现基于 CLI 的网络自动化。 1. Python Nornir 概…

jacoco增量覆盖率平台开发

先聊聊做这个平台的意义&#xff0c;从项目管理角度来说&#xff0c;测试说项目测试完成&#xff0c;该如何证明呢&#xff1f;一般情况下我们进行验收时没什么问题就算完成了&#xff0c;但是实际上测试很多情况并没有考虑到。所以该平台可以反哺测试的测试用例&#xff0c;让…

GO的服务

1.go的安装 1.1 确认版本go version go version go1.20.4 darwin/amd64 可以看到是macos10.14版本。如果是m1 需要安装对应的版本 1.2 用vscode 进行编写go的简单例子 先进入vscode的界面&#xff0c;新建一个目录为godemo&#xff0c;里面就是go的例子的工作目录&#xff0…

计算机的大小端存储模式(计算机小白必看!)

目录 1.什么是大端小端 2.为什么会有大小端模式之分呢&#xff1f; 3.如何判断当前机器为大端字节序还是小端字节序 本文将介绍计算机存储数据时的大小端问题 1.什么是大端小端 大端&#xff08;存储&#xff09;模式&#xff0c;是指数据的低位保存在内存的高地址中&…