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

news/2024/11/8 0:52:08/

前言

相信每个前端工程师,或者了解前端的人都知道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 cfor (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.ppmy.cn/news/99873.html

相关文章

K210入门-环境搭建与点灯测试(一)

目录 1、简介 2、资质查找 3、IDE下载安装 4、测试程序 4.1 测序复制 4.2 开发板选择 4.3 链接 4.4 效果展示 1、简介 本文主要针对小白使用K210进行入门,以及自己学习的总结与笔记使用。本文主要进行环境搭建与点灯测试。 2、资质查找 首先去官网进行资料下…

深度学习基本功3:NMS(Non-Maximum Suppression,非极大值抑制)算法原理及实现

文章目录 1. 为什么要使用NMS2. NMS算法原理2.1 IoU与置信度2.2 算法流程 3. Python代码实现 1. 为什么要使用NMS 大多数目标检测算法(稠密预测)在得到最终的预测结果时,特征图的每个位置都会输出多个检测结果,整个特征图上会出很…

14巧探细节:gRPC的UnknownService接口

gRPC UnknownServiceHandler是一个gRPC内置的一种拦截器,用于处理未知的服务请求。具体的使用案例可以是在服务端实现一个UnknownServiceHandler,当客户端请求一个不存在的服务时,服务端会返回一个自定义的错误信息,而不是默认的 gRPC 错误信息以提高服务的可读性。接下来让…

SPA首屏加载速度慢的怎么解决?

SPA首屏加载速度慢的怎么解决? 加载慢的原因 网络延时问题资源文件体积是否过大资源是否重复发送请求去加载了加载脚本的时候,渲染内容堵塞了 解决方案 1.减小入口文件体积 常用的手段是路由懒加载,把不同路由对应的组件分割成不同的代码…

上海城市开发者社区小聚有感

👏作者简介:大家好,我是Rockey,不知名企业的不知名Java开发工程师 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦 📝联系方式:he18339193956&…

几句命令搞定一个es:docker安装elasticsearch+可视化kibana

docker安装elasticsearch可视化kibana 写在前面es安装:docker安装elasticsearches搜索:安装elasticsearch插件IK分词器es可视化:docker安装kibana最后 写在前面 从自己知道es开始到写这篇文章差不多也有5年左右的时间了吧,之前总…

我的创作纪念日(第256天)

机缘 在学习数据结构的时候想要分享自己的学习成果记录自己所学习的知识,这样以后还可以回头来复习通过文章进行技术交流为了结识更多志同道合的人 收获 目前获得了129位粉丝的关注认识了和自己相同方向志同道合的朋友 日常 创作已经是你生活的一部分了有限的精力…

Golang单元测试详解(一):单元测试的基本使用方法

Golang 单元测试 Golang 中的单元测试是使用标准库 testing 来实现的,编写一个单元测试是很容易的: 创建测试文件:在 Go 项目的源代码目录下创建一个新的文件(和被测代码文件在同一个包),以 _test.go 为后…