TypeScript学习笔记(六)枚举

278 阅读2分钟

枚举(enum)

使用枚举可以帮我们定义一些有名字的数字常量,通过enum关键字来定义:

enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}

一个枚举类型可以包含0个或多个枚举成员,枚举成员具有一个数字值,它可以是常数或者计算出的值。 当满足下面的条件时,枚举成员是常数:

  • 不具备初始化函数,并且之前的枚举成员是常数。这种情况下,该枚举成员的值是上一个枚举成员的值 + 1。但如果是第一个枚举成员,如果他没有初始化函数,那他的初始值是 0 。
  • 枚举成员使用 常数枚举表达式 初始化, 什么是常数枚举表达式呢?它的特点是可以在编译阶段求值,当一个表达式符合下面的条件之一时,它是常数枚举表达式
    • 数字字面量
    • 引用之前定义的常数枚举成员(也可以是其他枚举类型的枚举成员)。如果这个成员是在同一个枚举类型中定义的,可以使用非限定名来引用。
    • 带括号的常数枚举表达式
    • +, -, ~ 一元运算符应用于常数枚举表达式
    • +, -, *, /, %, <<, >>, >>>, &, |, ^ 二元运算符,常数枚举表达式做为其一个操作对象。 若常数枚举表达式求值后为NaNInfinity,则会在编译阶段报错。 除了常数类型的枚举成员外,其他的枚举成员被当作是需要计算得出的值。
enum FileAccess {
    // 常数
    None,
    Read    = 1 << 1,
    Write   = 1 << 2,
    ReadWrite  = Read | Write,
    // 计算出的值
    G = "123".length
}

枚举是在运行时真正存在的一个对象,可以从枚举值到枚举名反向映射。

enum Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"

当访问枚举值时,为了避免生成多余的代码和间接引用,可以使用常数枚举。 常数枚举是在enum关键字前使用const修饰符。

const enum Enum {
    A = 1,
    B = A * 2
}

常数枚举只能使用常数枚举表达式并且不同于常规的枚举的是它们在编译阶段会被删除。 常数枚举成员在使用的地方被内联进来。 这是因为常数枚举不可能有计算成员

const enum Directions {
    Up,
    Down,
    Left,
    Right
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
// 生成后的代码 var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]; 

外部枚举

外部枚举用来描述已经存在的枚举类型的形状。

declare enum Enum {
    A = 1,
    B,
    C = 2
}

外部枚举和非外部枚举之间有一个重要的区别,在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的。