JavaScript 中你应该知道的 旧习惯 与 新习惯(三)

182 阅读3分钟

JavaScript 中你应该知道的 旧习惯 与 新习惯(三)

用 async / await 代替 Promise

旧习惯 使用 Promise

function fetchJSON(url){
    return fetch(url).then(
    	(response)=>return response.json();
    )
}

新习惯 使用 async/await

async function fetchJSON(url){
    const response = await fetch(url);
    return response.json();
}

使用模板字面量代替字符串连接

旧习惯

const getInfo = bird => bird.name + ' ' + bird.age;

新习惯

const getInfo = bird => `${bird.name} ${bird.age}`;

使用字符串迭代

旧习惯 使用下标访问字符串中的字符

const str = "abcde";
for (let i = 0; i < str.length; ++i){
    // str[i]
}

新习惯 视为可迭代对象

const str = "abcde";
for (const char of str){
    // char
}

使用 find 和 findIndex 方式来代替循环找数组中某个符合条件的

旧习惯 使用for循环 forEach filter取第一项等

let target;
let array = [{id:1},{id:2}];
for (let i = 0; i < array.length; ++i){
    if (array[i].id === 2){
        target = array[i];
        break;
    }
}

新习惯 使用 find 和 findIndex

let array = [{id:1},{id:2}];
let target = array.find(i => return i.id === 2);

使用 Array.fill 代替循环填充数组

旧习惯 使用for循环填充数组

// 一维度数组
const len = 5;
const array = new Array(len);
for (let i = 0; i < len; ++i){
    array[i] = 0;
}

// M*N数组
const M = 5;
const N = 5;
const array = new Array(M);
for (let i = 0; i < M; ++i){
    array[i] = new Array(N);
    for (let j = 0; i < N; ++j){
    	array[i][j] = 0;
	}
}

新习惯 使用fill

// 一维度数组
const len = 5;
const array = new Array(len).fill(0);

// M*N数组
const M = 5;
const N = 5;
// const array = new Array(M).fill(new Array(N).fill(0));
const array = new Array(M).fill(0).map(()=>new Array(N).fill(0)); 

读取文件时使用 readAsArrayBuffer 取代 readAsBinaryString

旧习惯 使用readAsBinaryString 来处理文件

新习惯 使用readAsArrayBuffer 来处理文件

使用Map代替对象

旧习惯 使用对象存储

const map = {};
const id = "1";
const obj = {};
map[id] = obj;

新习惯 使用Map

const store = new Map();
const id = {};
const obj = {};
store.set(id,obj);

// 使用
let target = stroe.get(id);

使用Set 代替对象做集合

旧习惯 使用对象的key来标记是否存在

let birds = {};
birds["xiaohong"] = true;
if(birds["xiaohong"]){
    // 存在
}

新习惯 使用Set

const birds = new Set();
birds.add("xiaohong");
if(birds.has("xiaohong")){
    // 存在
}

使用模块代替伪命名空间

旧习惯 导出一整个对象,jquery时代的操作

var utils = (function(utils){
    function toString(){
        
    }
    // ...
})(utils || {})

新习惯 使用ESM的导入导出操作

function toString(){
        
}
const utils = {
    toString:toString
}

export default utils;
export { toString };

参考资料:es6.ruanyifeng.com/#docs/modul…

将CJS、AMD和其他模块的转为 ESM

旧习惯 打包成CJS AMD 等其他格式,因为没有ESM

新习惯 使用ESM格式,至少新的要支持ESM,拥抱未来

使用通用的打包器而不是自研

旧习惯 自研一套打包器

新习惯 拥抱社区,使用通用的有社区支持的打包器

使用代理,而不是提供API来get,set 属性

旧习惯 直接提供整个对象,约定不修改

新习惯 改用代理

使用代理将部分判断与实现分开

旧习惯 将判断与功能实现写在一起

新习惯 可以考虑将功能函数写对象上,判断或者检测在代理上实现

使用二进制字面量

旧习惯 在一些可能更适合二进制的地方,使用十六进制数字

const flags = {
    a: 0x01,
    b: 0x02,
    c: 0x04,
    d: 0x08,
}

新习惯 在合理的地方采用二进制数字

const flags = {
    a: 0b00000001,
    b: 0b00000010,
    c: 0b00000100,
    d: 0b00001000,
}

这个多提一句,其实应用挺多的,比如Vue3 里面的 PatchFlags 来标记动静节点就是典型的,比如react的车道标记也是

使用新的Math函数,而不是各种自己实现的变通方式

旧习惯 使用代码自己实现

新习惯 使用新提供的Math 函数

//大部分用不到,这里写几个刷题可能会用到的
** =  Math.pow 
Math.sign(x); // 返回x的符号 【NaN,0,+1,-1】
Math.trunc(x);  // 直接返回整数部分

使用空值合并

旧习惯 代码判断并赋值

const data = res.data === null || res.data === undefined ? 200 : res.data;

新习惯 使用空值合并 ??

const data = res.data ?? 200;

使用可选链

旧习惯 先判断是否存在再调用

// 属性
let xiaohong = bird && bird.one && bird.one.name;
// 函数
if(xiaohong.talk){
    xiaohong.talk();
}

新习惯 使用可选链

// 属性
let xiaohong = bird?.one?.name;
// 函数
xiaohong.talk?.();