关于javascript:用-Enum-提高TypeScript代码的可读性

35次阅读

共计 4716 个字符,预计需要花费 12 分钟才能阅读完成。

Enum

Enum 是在 TypeScript 中新增的语法,也叫做 枚举 ,个别用它来治理多个 雷同系列 的常量(即不能被批改的变量),用于状态的判断。

在 Web 中比拟常见的状态判断,是在解决申请时,要针对不同的响应状态码做对应的解决:

const handleResponseStatus = (status: number): void => {switch (status) {
    case 200: // 申请胜利时
      // Do something...
      break;
    case 400: // 申请失败时
      // Do something...
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

但因为响应状态码都是事后定义好的,所以没什么争议,代码写成这样看也很失常,然而如果后端在服务器产生谬误时自定义了一些编码,并通知前端,这些代码都代表什么谬误,那么下面的函数可能会变成这样:

const handleWrongStatus = (status: string): void => {switch (status) {
    case 'A':
      // Do something...
      break;
    case 'B':
      // Do something...
      break;
    case 'C':
      // Do something...
      break;
    default:
      throw (new Error('No have wrong code!'));
  }
};

如果是这种代码,别说是刚接手的人,就算是你本人两星期前写的,恐怕不去翻文档也想不起它们都代表什么了吧。

然而如果善用 Enum,就能够防止上述产生的状况。

根本用法

先来看看 Enum 该怎么定义,它和 Object 的用法很像:

enum requestStatusCodes {
  error,
  success,
}

不须要在内容与名称之间加等号,间接在大括号内叙述该 Enum 中具备哪些变量,与其说是变量,不如说是常量更失当些,因为在 Enum 中的值是不可批改的,所以也不用放心这些定义好的规定会在代码执行的过程中产生扭转,导致执行谬误。

而既然 Enum 是用来定义同一个系列常量的,那这些常量应该都能保护特定的值。没错,在 Enum 中的每个常量,都能够通过 = 来指定具体的值。

但如果是像后面的 requestStatusCodes,没有为 errorsuccess 指定具体的值也不会出错,因为 TypeScript 会从 0 开始主动递增定义值,所以签名的 requestStatusCodes 会和上面的后果雷同:

enum requestStatusCodes {
  error = 0,
  success = 1,
}console.log(requestStatusCodes.error) // 0
console.log(requestStatusCodes.success) // 1

除了数字外,也能够定义为字串:

enum requestWrongCodes {
  missingParameter = 'A',
  wrongParameter = 'B',
  invalidToken = 'C',
}console.log(requestWrongCodes.wrongParameter) // 'B'

当然也能够在一个 enum 中设定不同的类型,但这样一点意义都没有:

enum requestStatusCodes {
  error = 0,
  success = 'OK',
}

理解根本的 Enum 怎么定义后,接着就来改写后面代码中的 handleResponseStatushandleWrongStatus,让它们在语义上可能更明确。

首先用 Enum 定义两者的状态形容:

enum requestStatusCodes {
  error = 400,
  success = 200,
}

enum requestWrongCodes {
  missingParameter = 'A',
  wrongParameterType = 'B',
  invalidToken = 'C',
}

而后批改 handleResponseStatushandleWrongStatus 中的 Switch 判断:


const handleResponseStatus = (status: number): void => {switch (status) {
    case requestStatusCodes.success:
      // Do something...
      break;
    case requestStatusCodes.error:
      // Do something...
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

const handleWrongStatus = (status: string): void => {
  // 如果感觉 requestWrongCodes.missingParameter 太长了,也能够用以下形式:const {missingParameter, wrongParameterType, invalidToken,} = requestWrongCodes;
  switch (status) {
    case missingParameter:
      // Do something...
      break;
    case wrongParameterType:
      // Do something...
      break;
    case invalidToken:
      // Do something...
      break;
    default:
      throw (new Error('No have wrong code!'));
  }
};

批改后的代码就变得直观多了,因为状态码都被放到了 Enum 中对立治理,所以就能用常量名来代表它们,之后不论过了多久,能够明确的晓得这里再做什么,甚至连注解或文档都不必写了,因为代码就是最好的文档。

善用 Enum 能使代码相对是不可或缺的,但就算没应用 TypeScript 也别灰心,因为 TypeScript 最终会被转换为 JavaScript,那来看看如何间接用 JavaScript 实现 Enum 吧!

用原生 JavaScript 实现 Enum

在后面说过 Enum 很像 Object,如果钻研一下 Enum 被编译成 javascript 之后的代码,就会发现还真的是 Object。

Enum 被编译后会变成 Key 和 Value 反向对应的对象,这样看起来非常简单,为了方便使用,上面把它的编译形式写成一个函数:

const newEnum = (descriptions) => {const result = {};
  Object.keys(descriptions).forEach((description) => {result[result[description] = descriptions[description]] = description;
  });
  return result;
};

const responseStatus = newEnum({
  error: 400,
  success: 200,
});

// {'200': 'success', '400': 'error', error: 400, success: 200}
console.log(responseStatus);

尽管失去的后果雷同,然而丢失了 Enum 中最可贵的 常量 特色,如果不能让它变成不可批改,那就有可能会在代码里不经意地改变它,导致执行后果可能出错,于是能够在最初利用 Object.freeze(),让内部操作无奈新增、删除或从新定义任何 Property:


const newEnum = (descriptions) => {const result = {};
  Object.keys(descriptions).forEach((description) => {result[result[description] = descriptions[description]] = description;
  });
  return Object.freeze(result);
};

const responseStatus = newEnum({
  error: 400,
  success: 200,
});

// 即便不小心批改了
responseStatus['200'] = 'aaaaaaaa';

// 依然是 {'200': 'success', '400': 'error', error: 400, success: 200}
console.log(responseStatus);

这样就能简略在 JavaScript 中实现 Enum 了。

const Enum 的用法

从后面的 JavaScript 代码中能够看到 Enum 编译过后会变成 Key 和 Value 相互对应的 Object,也就是说不论是用 Key 还是 Value 都能够取出对应的值,

然而如果用 const 申明 Enum,编译之后就不会产生 Object。

间接看例子,假如我把 responseStateconst 从新生命,且也是以 handleResponseStatus 应用该 Enum 做判断:

enum responseStatus {
  error = 400,
  success = 200,
}

const handleResponseStatus = (status: number): void => {switch (status) {
    case responseStatus.success:
      console.log('申请胜利!');
      break;
    case responseStatus.error:
      console.log('申请失败!');
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

看起来一切正常,不过在编译后的 JavaScript 中,会发现 Enum 并没有产生 Object,而是间接用 const 申明在 Enum 中的值。

const 申明 Enum 有几个益处:

  1. 假如要用到的 Enum 十分多,那在执行时就会不停地应用 IIFE 产生 Object 将 Key 和 Value 绑定到 Object,会造成一些效率上的损失,也会减少内存,然而 const 并不会产生 Object,也就不会有以上的问题。
  2. 就算到的 Enum 不多,判断时也须要始终从 Object 中找出对应的值,而如果是用 const 申明 Enum,在编译成 JS 时就将申明的值间接放入判断中。

不过这样也就没法从 Enum 中反向取值了,因为它并不会产生对象:

const enum responseStatus {
  error = 400,
  success = 200,
}// 会出错,因为曾经没有对象可供查找了
console.log(responseStatus[400])// 但这个不会有问题,因为编译的时候会间接填值
console.log(responseStatus.error)// 编译后:// console.log(400)


本文首发微信公众号:前端先锋

欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章


欢送持续浏览本专栏其它高赞文章:

  • 深刻了解 Shadow DOM v1
  • 一步步教你用 WebVR 实现虚拟现实游戏
  • 13 个帮你进步开发效率的古代 CSS 框架
  • 疾速上手 BootstrapVue
  • JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
  • WebSocket 实战:在 Node 和 React 之间进行实时通信
  • 对于 Git 的 20 个面试题
  • 深刻解析 Node.js 的 console.log
  • Node.js 到底是什么?
  • 30 分钟用 Node.js 构建一个 API 服务器
  • Javascript 的对象拷贝
  • 程序员 30 岁前月薪达不到 30K,该何去何从
  • 14 个最好的 JavaScript 数据可视化库
  • 8 个给前端的顶级 VS Code 扩大插件
  • Node.js 多线程齐全指南
  • 把 HTML 转成 PDF 的 4 个计划及实现

  • 更多文章 …

正文完
 0