您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

TypeScript 枚举(Enum)

本节介绍枚举类型的定义及其使用,需要定义一组相同的常量数据时,应该立即想到枚举类型。在学习过程中,需要注意枚举类型的正向映射和反向映射,可以通过编译后的 JavaScript 源码进行分析,为什么可以进行反向映射。

使用枚举我们可以定义一些带名字的常量。TypeScript 数字的和基于字符串的枚举。

枚举类型弥补了 JavaScript 的设计不足,很多语言都拥有枚举类型。

当我们需要一组相同下的数据时,枚举类型就很有用了。

enum Direction { Up, Down, Left, Right }

enum Months { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }

enum Size { big = '大', medium = '中', small = '小' }

enum Agency { province = , city = , district =  }
@H__109@

解释:

中通过枚举类型分别声明了:不同的 方向@H__109@,一年内不同的 月份@H__109@,商品的不同 尺寸@H__109@,经销商的不同 级别@H__109@,这样的一组常量数据,是在相同下的不同表示。

声明枚举类型,如果没有赋值,它们的值认为数字类型且从 0 开始累加:

enum Months {
  Jan,
  Feb,
  Mar,
  Apr
}

Months.Jan ===  // true
Months.Feb ===  // true
Months.Mar ===  // true
Months.Apr ===  // true
@H__109@

现实中月份是从 1 月开始的,那么只需要这样:

// 从第数字赋值,往后依次累加
enum Months {
  Jan = ,
  Feb,
  Mar,
  Apr
}

Months.Jan ===  // true
Months.Feb ===  // true
Months.Mar ===  // true
Months.Apr ===  // true
@H__109@

解释:

第 3 行,从 Jan@H__109@ 被赋值为 1@H__109@ 开始,后续的值依次累加。

枚举类型的值为字符串类型

enum TokenType {
  ACCESS = 'accessToken',
  REFRESH = 'refreshToken'
}

// 两种不同的取值写法
console.log(TokenType.ACCESS === 'accessToken')        // true
console.log(TokenType['REFRESH'] === 'refreshToken')   // true
@H__109@

解释: 枚举的取值,有 TokenType.ACCESS@H__109@ 和 TokenType['ACCESS']@H__109@ 这两种不同的写法,是相同的。

数字类型和字符串类型可以混合使用,但是不建议:

enum BooleanLikeHeterogeneousEnum {
    No = ,
    Yes = "YES",
}
@H__109@

枚举类型的值可以是简单的计算表达式:

enum Calculate {
  a,
  b,
  expired =  *  * ,
  length = 'imooc'.length,
  plus = 'hello ' + 'world'
}

console.log(Calculate.expired)   // 86400
console.log(Calculate.length)    // 5
console.log(Calculate.plus)      // hello world
@H__109@

Tips:

所谓的反向映射就是指枚举的取值,不但可以正向的 Months.Jan@H__109@ 这样取值,也可以反向的 Months[1]@H__109@ 这样取值。

enum Months {
  Jan = ,
  Feb,
  Mar,
  Apr
}
@H__109@

将上面的进行编译,查看编译后的 JavaScript :

'use strict'
var Months;
(function (Months) {
  Months[Months['Jan'] = ] = 'Jan'
  Months[Months['Feb'] = ] = 'Feb'
  Months[Months['Mar'] = ] = 'Mar'
  Months[Months['Apr'] = ] = 'Apr'
})(Months || (Months = {}))
@H__109@

通过查看编译后的,可以得出:

console.log(Months.Mar === ) // true

// 那么反过来能取到 Months[3] 的值吗?
console.log(Months[])  // 'Mar'

// 所以
console.log(Months.Mar === )     // true
console.log(Months[] === 'Mar')  // true
@H__109@

Tips:

在枚举上使用 const@H__109@ 修饰符:

enum Months {
  Jan = ,
  Feb,
  Mar,
  Apr
}

const month = Months.Mar
@H__109@

查看一下编译后的:

'use strict'
const month =  /* Mar */
@H__109@

发现枚举类型应该编译出的对象没有了,只剩下 month@H__109@ 常量。这就是使用 const@H__109@ 关键字声明枚举的作用。因为变量 month@H__109@ 已经使用过枚举类型,在编译阶段 TypeScript 就将枚举类型抹去,这也是提升的一种方案。

分开声明相同的枚举类型,会合并:

enum Months {
  Jan = ,
  Feb,
  Mar,
  Apr
}

enum Months {
  May = ,
  Jun
}

console.log(Months.Apr) // 4
console.log(Months.Jun) // 6
@H__109@

编译后的 JavaScript :

'use strict'
var Months;
(function (Months) {
  Months[Months['Jan'] = ] = 'Jan'
  Months[Months['Feb'] = ] = 'Feb'
  Months[Months['Mar'] = ] = 'Mar'
  Months[Months['Apr'] = ] = 'Apr'
})(Months || (Months = {}));
(function (Months) {
  Months[Months['May'] = ] = 'May'
  Months[Months['Jun'] = ] = 'Jun'
})(Months || (Months = {}))

console.log(Months.Apr) // 4
console.log(Months.Jun) // 6
@H__109@

通过本节的介绍需要知道:


联系我
置顶