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 ,没有为 error 或 success 指定具体的值也不会出错,因为 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 怎么定义后,接着就来改写前面代码中的 handleResponseStatus 和 handleWrongStatus ,让它们在语义上能够更明确。
首先用 Enum 定义两者的状态描述:
enum requestStatusCodes {
error = 400,
success = 200,
}
enum requestWrongCodes {
missingParameter = 'A',
wrongParameterType = 'B',
invalidToken = 'C',
}
然后修改 handleResponseStatus 和 handleWrongStatus 中的 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 吧!
在前面说过 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 了。
从前面的 JavaScript 代码中可以看到 Enum 编译过后会变成 Key 和 Value 互相对应的 Object ,也就是说不管是用 Key 还是Value 都可以取出对应的值,
但是如果用 const 声明 Enum ,编译之后就不会产生 Object。
直接看例子,假设我把 responseState 用 const 重新生命,且也是以 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 有几个好处:
不过这样也就没法从 Enum 中反向取值了,因为它并不会产生对象:
const enum responseStatus {
error = 400,
success = 200,
}// 会出错,因为已经没有对象可供查找了
console.log(responseStatus[400])// 但这个不会有问题,因为编译的时候会直接填值
console.log(responseStatus.error)// 编译后:
// console.log(400)
近些日子,我使用了新语言编程,从JavaScript,切确地说是Elm,转成TypeScript。在本文中,我将继续深挖一些我非常喜欢的TypeScript特性。
TypeScript 和 JavaScript 是目前项目开发中较为流行的两种脚本语言,我们已经熟知 TypeScript 是 JavaScript 的一个超集,但是 TypeScript 与 JavaScript 之间又有什么样的区别呢?
Nerv_是一款由京东凹凸实验室打造的类 React 前端框架,基于虚拟 DOM 技术的 JavaScript(TypeScript) 库。它基于React标准,提供了与 React 16 一致的使用方式与 API。
交叉类型:将多个类型合并为一个类型、联合类型:表示取值可以为多种类型中的一种、混合类型:一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性、类型断言:可以用来手动指定一个值的类型
在做比较大的,多人合作的项目的时候,TypeScript会更加地适合,这得益于它的可读性,面向对象性以及易于重构的特点。但如果只是自己做小程序,不需要太多人参与的时候,JavaScript则会更加简单。
有两种方式安装TypeScript,如何创建第一个TypeScript文件,在TypeScript中,可以使用interface来描述一个对象有firstName和lastName两个属性,TypeScript支持JavaScript的新功能,其中很重要的一个功能就是基于类的面向对象编程
使用TypeScript已经有了一段时间,这的确是一个好东西,虽说在使用的过程中也发现了一些bug,不过都是些小问题,所以整体体验还是很不错的。有关TypeScript声明类型声明相关的目前就总结了这些比较常用的
谷歌在很早之前就张开双臂拥抱 Web 应用程序,Gmail 已经发布 14 年了。当时,JavaScript 的世界是疯狂的。Gmail 工程师不得不为 IE 糟糕的垃圾回收算法捏一把汗,他们需要手动将字符串文字从 for 循环中提取出来,以避免 GC 停顿
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。
差不多两年前,我在一个创业团队中开始了一个全新的项目。用到的全都是类似Microservices,docker,react,redux这些时髦的东西。我在前端技术方面积累了一些类似的经验
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!