29、枚举

枚举

  • 枚举使用场景
  • 枚举语法及特性
    • 特性:
  • 手动给枚举赋值
    • 手动赋值项和未手动赋值项重复
    • 手动赋值项智能赋值数字?NO
    • 常数项和计算项
    • 常数枚举
    • 外部枚举

枚举使用场景

枚举类型 用于取值被限定在一定范围内的场景。
demo: 一周只能有七天,颜色限定为红黄绿

枚举语法及特性

// 简单例子
enum Days {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday,
}

特性:

枚举成员会被赋值为从0开始递增的数字,同时也会对枚举值到枚举名进行反向映射

enum Days {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday,
}
console.log(Days['Monday']=== 0) // true
console.log(Days['Tuesday']=== 1) // trueconsole.log(Days[5] === 'Saturday') // true
console.log(Days[6] === 'Sunday') // true
enum Days {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday,
}
// js输出为
var Days;
(function (Days) {Days[Days["Monday"] = 0] = "Monday";Days[Days["Tuesday"] = 1] = "Tuesday";Days[Days["Wednesday"] = 2] = "Wednesday";Days[Days["Thursday"] = 3] = "Thursday";Days[Days["Friday"] = 4] = "Friday";Days[Days["Saturday"] = 5] = "Saturday";Days[Days["Sunday"] = 6] = "Sunday";
})(Days || (Days = {}));
// 上述函数自执行后,得到如下对象
{
0: "Monday"
1: "Tuesday"
2: "Wednesday"
3: "Thursday"
4: "Friday"
5: "Saturday"
6: "Sunday"
Friday: 4
Monday: 0
Saturday: 5
Sunday: 6
Thursday: 3
Tuesday: 1
Wednesday: 2
}

手动给枚举赋值

1、未手动赋值的枚举项会接着上一个枚举项递增,如下demo

enum Color {A = 7,B = 1,C,D,E,F,G
}
console.log(Color['A'] === 7) // true
console.log(Color['B'] === 1) // true
console.log(Color['C'] === 2) // true
console.log(Color['G'] === 6) // true

手动赋值项和未手动赋值项重复

未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点,并没有什么报错,也没有进行一些相关的提示

enum Color {A = 3,B = 1,C,D,E,F,G
}
console.log(Color['A'] === 3) // true
console.log(Color['D'] === 3) // true
console.log(Color[3] === 'A') // false
console.log(Color[3] === 'D') // true

上面的例子中,递增到 3 的时候与前面的 A 的取值重复了,但是 TypeScript 并没有报错,导致 Days[3] 的值先是 “A”,而后又被 “D” 覆盖了。编译的结果是

上述的ts编译为js,如下:

var Color;
(function (Color) {Color[Color["A"] = 3] = "A";Color[Color["B"] = 1] = "B";Color[Color["C"] = 2] = "C";Color[Color["D"] = 3] = "D";Color[Color["E"] = 4] = "E";Color[Color["F"] = 5] = "F";Color[Color["G"] = 6] = "G";
})(Color || (Color = {}));

所以实际使用中,要避免上述情况的出现

手动赋值项智能赋值数字?NO

手动赋值的枚举项可以不是数字,此时需要使用类型断言来让 tsc 无视类型检查 (编译出的 js 仍然是可用的)

enum Color1 {A = 1,B ,C ,D ,E ,F = <any>'S'
}
console.log(Color1['A'] === 1) // true
console.log(Color1['D'] === 4) // true
console.log(Color1[4] === 'D') // true
console.log(Color1['F'] === 'S') // true
console.log(Color1['S'] === 'F') // true
// 会报错:TS2367: This comparison appears to be unintentional because the types 'Color1' and 'string' have no overlap
// 这种比较似乎是无意的,因为类型'Color1'和'string'没有重叠// 编译后
var Color1;
(function (Color1) {Color1[Color1["A"] = 1] = "A";Color1[Color1["B"] = 2] = "B";Color1[Color1["C"] = 3] = "C";Color1[Color1["D"] = 4] = "D";Color1[Color1["E"] = 5] = "E";Color1[Color1["F"] = 'S'] = "F";
})(Color1 || (Color1 = {}));
console.log(Color1['A'] === 1);
console.log(Color1['D'] === 4);
console.log(Color1[4] === 'D');
console.log(Color1['F'] === 'S');
console.log(Color1['S'] === 'F');

当给枚举值赋值小数时,依次递增的特性是正常的,步长为1

enum Color2 {A = 7,B = 1.3,C ,D
}
console.log(Color2['A'] === 7) // true
console.log(Color2['C'] === 2.3) // true
console.log(Color2['D'] === 3.3)// true// 编译后的js
var Color2;
(function (Color2) {Color2[Color2["A"] = 7] = "A";Color2[Color2["B"] = 1.3] = "B";Color2[Color2["C"] = 2.3] = "C";Color2[Color2["D"] = 3.3] = "D";
})(Color2 || (Color2 = {}));

常数项和计算项

前面的demo一直都是常数项
下方demo中 ‘zhang’.length就是一个计算项
计算属性放在枚举最后面是没问题,通过js可以看到,还是正常的

enum Color3 {A ,B ,C ,D = 'zhang'.length
}
console.log(Color3['A'] === 0) // true
console.log(Color3['D'] === 5) // true
// 编译后
var Color3;
(function (Color3) {Color3[Color3["A"] = 0] = "A";Color3[Color3["B"] = 1] = "B";Color3[Color3["C"] = 2] = "C";Color3[Color3["D"] = 'zhang'.length] = "D";
})(Color3 || (Color3 = {}));
console.log(Color3['A'] === 0);
console.log(Color3['D'] === 5);

计算属性放在枚举最前面,可能会导致一些问题:如果紧接在计算所得项后面的是未手动赋值的项,那么它就会因为无法获得初始值而报错(ts提示枚举值必须有初始值)

enum Color3 {A = 'zhang'.length,B ,C ,D 
}
console.log(Color3['A'] === 5) // true
console.log(Color3['D'] === 8) // false
// 编译报错:Enum member must have initializer  枚举成员必须有初始化式// 编译后
var Color3;
(function (Color3) {Color3[Color3["A"] = 'zhang'.length] = "A";Color3[Color3["B"] = void 0] = "B";Color3[Color3["C"] = void 0] = "C";Color3[Color3["D"] = void 0] = "D";
})(Color3 || (Color3 = {}));
console.log(Color3['A'] === 5);
console.log(Color3['D'] === 8);

下面是常数项和计算所得项的完整定义:

当满足以下条件时,枚举成员被当作是常数:

1、不具有初始化函数并且之前的枚举成员是常数。在这种情况下,当前枚举成员的值为上一个枚举成员的值加 1。但第一个枚举元素是个例外。如果它没有初始化方法,那么它的初始值为 0。

2、枚举成员使用常数枚举表达式初始化。常数枚举表达式是 TypeScript 表达式的子集,它可以在编译阶段求值。当一个表达式满足下面条件之一时,它就是一个常数枚举表达式

  • 数字字面量
  • 引用之前定义的常数枚举成员(可以是在不同的枚举类型中定义的)如果这个成员是在同一个枚举类型中定义的,可以使用非限定名来引用
  • 带括号的常数枚举表达式
  • +, -, ~ 一元运算符应用于常数枚举表达式
  • +, -, *, /, %, <<, >>, >>>, &, |, ^ 二元运算符,常数枚举表达式做为其一个操作对象。若常数枚举表达式求值后为 NaN 或 Infinity,则会在编译阶段报错

所有其它情况的枚举成员被当作是需要计算得出的值。

常数枚举

常数枚举是使用 const enum 定义的枚举类型
常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员,如下编译后的代码可以看下(普通枚举编译后是一个自执行函数)

  Red ,Green ,Blue
}
let kate = [Color4.Red, Color4.Green, Color4.Blue]
console.log(kate)
// 编译之后
let kate = [0 /* Color4.Red */, 1 /* Color4.Green */, 2 /* Color4.Blue */];
console.log(kate);

常数枚举中,不能含有计算计算成员
以下情况会报错:

const enum Color4 {Red ,Green ,Blue = 'blue'.length
}
let kate = [Color4.Red, Color4.Green, Color4.Blue]
console.log(kate)
// 编译会报错
// error TS2474: const enum member initializers must be constant expressions.// 编译后 编译后的js也是没办法运行的
let kate = [0 /* Color4.Red */, 1 /* Color4.Green */, Color4.Blue];
console.log(kate);

外部枚举

1、外部枚举(Ambient Enums)是使用 declare enum 定义的枚举类型
2、declare定义的类型只会用于编译时的检查,编译结果实际是会被删除的
3、外部枚举与声明语句一样,常出现的声明文件中

declare  enum Color5 {A,B,C,D
}
let Dire =[Color5.A, Color5.B, Color5.C, Color5.D]
console.log(Dire)
// 编译后
let Dire = [Color5.A, Color5.B, Color5.C, Color5.D];
console.log(Dire);
// 编译后的上述文件,肯定是运行失败的,Color就没有去定义怎么成功?

同时使用 declare 和 const 也是可以外部枚举的

declare const enum Color6 {A,B,C
}
let kate = [Color6.A, Color6.B, Color6.C]
// 编译后
let kate = [0 /* Color6.A */, 1 /* Color6.B */, 2 /* Color6.C */];

最后备注一下:其实枚举类型的概念是来源于c#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/126564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sqlLite 如何使用数据库连接池

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 一、前言 编写的一个jar包工具中&#xff…

JS(JavaScript) 实现延迟等待(sleep方法)

起因&#xff1a; 只使用 setTimeout 会产生嵌套等方面的问题&#xff0c;达不到想要的效果。 解决方法&#xff1a; 使用 async/await 还有 Promise 相结合的方式来解决问题。 直接上代码&#xff1a; function sleep(time) {return new Promise((resolve) > setTimeout…

公众号留言功能报价是多少?值得开通吗?

为什么公众号没有留言功能&#xff1f;根据要求&#xff0c;自2018年2月12日起&#xff0c;新申请的微信公众号默认无留言功能。有些人听过一个说法&#xff1a;公众号粉丝累计到一定程度或者原创文章数量累计到一定程度就可以开通留言功能。其实这个方法是2018年之前才可以&am…

三氧化二铁纳米片

&#xff08;西&#xff09;三氧化二铁纳米片 &#xff08;安&#xff09;名称&#xff1a;三氧化二铁纳米片 &#xff08;瑞&#xff09;CAS&#xff1a;1309-37-1 &#xff08;禧&#xff09;分子式&#xff1a;Fe2O3 &#xff08;生&#xff09;外观&#xff1a;白色粉末…

链表的引入

什么是链表 链表一种线性的数据结构&#xff0c;通过指针将一个个零散的内存块连接起来&#xff0c;链表的每个内存块称为结点。结构体指针在这里得到了充分的利用。 为什么要使用链表 链表可以动态的进行存储分配&#xff0c;也就是说&#xff0c;链表是一个功能极为强大的数…

518抽奖软件,是否支持作弊~内定~指定中奖人~设置范围

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 主打纯净&#xff0c;不可作弊 市面上&…

7. 一文快速学懂常用工具——Makefile

本章讲解知识点 引言 Makefile Makefile 入门 本专栏适合于软件开发刚入职的学生或人士&#xff0c;有一定的编程基础&#xff0c;帮助大家快速掌握工作中必会的工具和指令。本专栏针对面试题答案进行了优化&#xff0c;尽量做到好记、言简意赅。如专栏内容有错漏&#xff0…

Flask 网站装潢, 简易更换模板

Flask 网站装潢&#xff0c;简易更换模板 本博文找个好看的网页模板&#xff0c;并简单改一改变成flask模板&#xff0c;并展示 主博客目录&#xff1a;《从零开始学习搭建量化平台笔记》 文章目录 Flask 网站装潢&#xff0c;简易更换模板下载模板Python 自动生成目录修改目录…

C# 使用 REST API HTTP 客户端生成器

本文内容 使用 AutoClientAttribute使用谓词属性定义 HTTP 方法HTTP 有效负载HTTP 头 显示另外 2 个 备注 此 API 是实验性的。 它可能会在后续版本的库中更改&#xff0c;并且无法保证向后兼容性。 HttpClient是使用 REST API 的好方法&#xff0c;但存在挑战。 其中一个挑…

CMake基础【学习笔记(八)】

声明此博客为转载 CMake基础 文章目录 CMake基础一、准备知识1.1 C的编译过程1.2 静态链接库和动态链接库1.3 为什么需要CMake1.3.1 g 命令行编译1.3.2 CMake简介 二、CMake基础知识2.1 安装2.2 第一个CMake例子2.3 语法基础2.3.1 指定版本2.3.2 设置项目2.3.3 添加可执行文件…

华纳云 宝塔怎么配置香港服务器多ip?

宝塔面板是一款开源的服务器管理面板&#xff0c;提供了简单易用的图形化界面&#xff0c;使用户能够轻松管理和配置服务器。通过切换到香港服务器多IP&#xff0c;用户可以拥有更多的IP资源&#xff0c;提供更灵活的网络服务。 配置香港服务器多IP 1.登录宝塔面板 打开浏览器&…

Goby 漏洞发布| Cisco IOS XE ebui_wsma_http 接口权限绕过漏洞(CVE-2023-20198)

漏洞名称&#xff1a; Cisco IOS XE ebui_wsma_http 接口权限绕过漏洞&#xff08;CVE-2023-20198&#xff09; English Name&#xff1a; Cisco IOS XE ebui_wsma_http API Permission Bypass Vulnerability (CVE-2023-20198) CVSS core: 10 影响资产数&#xff1a; 307282…

kafka为什么如此之快?

天下武功&#xff0c;唯快不破。同样的&#xff0c;kafka在消息队列领域&#xff0c;也是非常快的&#xff0c;这里的块指的是kafka在单位时间搬运的数据量大小&#xff0c;也就是吞吐量&#xff0c;下图是搬运网上的一个性能测试结果&#xff0c;在同步发送场景下&#xff0c;…

以八数码问题为例实现A*算法的求解(未完结)

八数码&#xff1a; 在一个 33 的网格中&#xff0c;1∼8 这 8 个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一的数字交换&#xff08;如果存在&#xff09;。…

(11月4日)GBASE南大通用 x openGauss Meetup,欢迎报名

由openGauss社区、天津南大通用数据技术股份有限公司主办&#xff0c;伟仕佳杰科技有限公司、神州数码&#xff08;中国&#xff09;有限公司协办的“GBASE南大通用 x openGauss Meetup”活动将于2023年11月4日&#xff08;周六&#xff09;在合肥市高新区云飞路66号天源迪科科…

3DEXPERIENCE云端项目管理小工具--Project Planner项目策划者角色

云端3DEXPERIENCE平台提供了一个协作环境&#xff0c;使企业和个人能够以全新的方式实现创新。它将人员、创意、数据和解决方案连接到一个始终在线且可用的协作和交互环境中&#xff0c;可以帮助您的企业提高执行力、生产率并加速创新。 3DEXPERIENCE中的Project Planner项目策…

BUUCTF 后门查杀 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 小白的网站被小黑攻击了&#xff0c;并且上传了Webshell&#xff0c;你能帮小白找到这个后门么&#xff1f;(Webshell中的密码(md5)即为答案)。 密文&#xff1a; 下载附件&#xff0c;解压得到一个网站文件夹。 解…

Nginx搭载负载均衡及前端项目部署

目录 ​编辑 一.Nginx安装 1.安装所需依赖 2.下载并解压Nginx安装包 3.安装nginx 4.启动Nginx服务 二.Tomcat负载均衡 1.准备环境 1.1 准备两个Tomcat 1.2 修改端口号 1.3 配置Nginx服务器集群 2.效果展示 ​编辑三.前端项目打包 ​编辑四.前端项目部署 1.上传项目…

YOLO目标检测——安全帽佩戴检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;安全帽佩戴检测数据集可以用于实时检测工作人员是否按照要求佩戴了安全帽&#xff0c;以保障他们的安全数据集说明&#xff1a;安全帽佩戴检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;图片分为带头盔和没带头…

云原生周刊:ingress2gateway 发布 | 2023.10.30

开源项目推荐 m9sweeper m9sweeper 是一个免费且简单的 Kubernetes 安全平台。它将行业标准的开源实用程序集成到一站式 Kubernetes 安全工具中&#xff0c;该工具可以帮助大多数 Kubernetes 管理员保护 Kubernetes 集群以及集群上运行的应用程序。 Kairos Kairos 是在 Kub…