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

news/2024/7/10 23:56:22 标签: es6, javascript, 开发语言

前言

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

1、 模板字符串

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

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

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

2、Symbol

①唯一值

javascript">// 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;

②魔术字符串

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

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

直接贴代码更直观:

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

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

在这里插入图片描述

3、Set 和 Map

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

javascript">[...new Set(array)]

②Map优化条件语句

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

// 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更好

javascript">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是解决‘先后问题’(需要先得到一个参数才能解决另一件事情的时候)的一个很好的方案。

javascript">// 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,表示无论如何最后都会执行的代码。

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

6、Async

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

javascript">// 例子 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)
};

错误捕获

javascript">// 例子 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看情况使用,代码更加优雅。

javascript">// 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、函数

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

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

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

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

javascript">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.niftyadmin.cn/n/369437.html

相关文章

子串--子字符串 0528

210102 201012 A1A2…An An…A2A1 如何做, 翻转的是21,因为2>1; 翻转的是210,因为2>0; 翻转的是2101,因为2>1; 翻转的是21010,因为2>0; 翻转的是210102,因为22且1&…

Linux——使用命令行参数管理环境变量

目录 使用命令行参数获取用户在DOS命令行输入的指令: 方法:代码如下: 使用命令行参数获取并打印部分或者整体环境变量的方法: 方法1: 运行结果: 方法2:使用外部链接environ: 使用命令行参数…

2023.05.28 学习周报

文章目录 摘要文献阅读1.题目2.现有方法存在的局限性3.SR-GNN模型4.模型的组成部分4.1 构图4.2 item向量表示4.3 session向量表示4.4 预测模块 5.实验与分析5.1 数据集5.2 比较方法5.3 评估指标5.4 实验结果 6.结论 有限元法1.一个例子2.进一步 深度学习1.张量场2.对流-扩散方程…

鬼影、雨雪天气点云噪声处理

雨雪天气点云噪声处理 在雨雪天气中,点云噪声可能来自以下几个方面: 雨滴、雪花等降水物体对激光雷达的反射造成的干扰;湿度、温度等气象因素对激光雷达的影响;环境中的遮挡物或反射体造成的多次反射或回波。 为解决点云噪声问…

jQuery-从左到右、从右到左

<!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>从左到右、从右到左</title> <style type"text/css"> select { …

【SA8295P 源码分析】07 - XBL Loader 解析 sbl1_config_table 规则分析

【SA8295P 源码分析】07 - XBL Loader 解析 sbl1_config_table 规则分析 一、SBL1(XBL Loader) 解析 sbl1_config_table1.1 sbl1_config_process_bl (config_context_handle, sbl1_config_table) 代码分析1.2 boot_config_process_entry (crt_config_context_handle) 代码分析…

HCIA-RSTP,MSTP

目录 STP的不足 RSTP对STP的改进 1&#xff0c;配置BPDU的处理发生变化&#xff1a; 2&#xff0c;配置BPDU的格式发生变化&#xff0c;充分利用STP的flag字段&#xff0c;明确接口角色。 3&#xff0c;RSTP拓扑处理&#xff1a; 端口角色&#xff1a; MSTP&#xff08;多…

什么是分段路由?如何在网络中实施分段路由?

在计算机网络中&#xff0c;分段路由&#xff08;Subnetting&#xff09;是一种将一个大的网络划分为多个较小子网的技术。它允许网络管理员更有效地分配 IP 地址和管理网络流量。本文将详细介绍分段路由的概念、原理以及如何在网络中实施分段路由。 1. 分段路由的概念 分段路…