• Typescript 实战 --- (2)枚举


    枚举(Enum)是一个命名元素的集合,用于取值被限定在一定范围内的场景。
     
    作用:将程序中不容易记忆的硬编码,或者是在未来会发生改变的常量抽取出来,定义成枚举类型,以此来提高程序的可读性和可维护性
     
    语法:
    enum 枚举类名 {
        枚举成员1, 枚举成员2, 枚举成员3... ... 枚举成员n;
      }
    1、数字枚举
    使用枚举可以定义一些有名字的数字常量,枚举类型会被编译成一个双向映射的对象。枚举成员会被赋值为从0开始递增的数字,同时,也会被枚举值到枚举名进行反向映射
    enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }
    
    console.log('Days', Days);
    
    // { 
    //   '0': 'Sun',
    //   '1': 'Mon',
    //   '2': 'Tue',
    //   '3': 'Wed',
    //   '4': 'Thu',
    //   '5': 'Fri',
    //   '6': 'Sat',
    //   Sun: 0,
    //   Mon: 1,
    //   Tue: 2,
    //   Wed: 3,
    //   Thu: 4,
    //   Fri: 5,
    //   Sat: 6 
    // }
    
    console.log('Days[0]:', Days[0]);   // Days[0]: Sun
    console.log('Days.Sun:', Days.Sun); // Days.Sun: 0
    console.log('Days[Days.Sun]:', Days[Days.Sun])  // Days[Days.Sun]: Sun

    上例中,枚举类Days被编译成了一个js对象,该对象首先以枚举名为key,以数字常量为value,逐对新增;然后以数字常量为key,枚举值为value,逐对新增。由此,建立了一个枚举值和数字常量双向映射的对象

    var Days;
    (function (Days) {
        Days[Days["Sun"] = 0] = "Sun";
        Days[Days["Mon"] = 1] = "Mon";
        Days[Days["Tue"] = 2] = "Tue";
        Days[Days["Wed"] = 3] = "Wed";
        Days[Days["Thu"] = 4] = "Thu";
        Days[Days["Fri"] = 5] = "Fri";
        Days[Days["Sat"] = 6] = "Sat";
    })(Days || (Days = {}));
    默认情况下,第一个枚举成员的值是0,后面的枚举成员的值依次加1。也可以
    enum Color1 { Red, Green, Blue };
    enum Color2 { Red = 2, Green, Blue };
    enum Color3 { Red, Green = 3, Blue };
    enum Color4 { Red, Green, Blue = 0 }; // 不建议
    enum Color5 { Red = -5, Green, Blue = 0 }; // 不建议
    enum Color6 { Red = -6, Green, Blue };
    
    console.log('Color1: ', Color1);
    console.log('Color2: ', Color2);
    console.log('Color3: ', Color3);
    console.log('Color4: ', Color4);
    console.log('Color5: ', Color5);
    console.log('Color6: ', Color6);
    
    // Color1:  { '0': 'Red', '1': 'Green', '2': 'Blue', Red: 0, Green: 1, Blue: 2 }
    // Color2:  { '2': 'Red', '3': 'Green', '4': 'Blue', Red: 2, Green: 3, Blue: 4 }
    // Color3:  { '0': 'Red', '3': 'Green', '4': 'Blue', Red: 0, Green: 3, Blue: 4 }
    // Color4:  { '0': 'Blue', '1': 'Green', Red: 0, Green: 1, Blue: 0 }
    // Color5:  { '0': 'Blue', Red: -5, '-5': 'Red', Green: -4, '-4': 'Green', Blue: 0 }
    // Color6:  { Red: -6, '-6': 'Red', Green: -5, '-5': 'Green', Blue: -4, '-4': 'Blue' }
    2、字符串枚举
    字符串枚举是不可以做双向映射的,只有枚举成员的名称作为key
    enum OrderStatus {
      Created = '已创建',
      Cancelled = '已取消'
    }
    
    // 编译
    var OrderStatus;
    (function (OrderStatus) {
        OrderStatus["Created"] = "u5DF2u521Bu5EFA";
        OrderStatus["Cancelled"] = "u5DF2u53D6u6D88";
    })(OrderStatus || (OrderStatus = {}));
    
    
    console.log(OrderStatus);
    // { Created: '已创建', Cancelled: '已取消' }
    3、异构枚举
    把数字枚举和字符串枚举混用,就形成了异构枚举,这种方式很容易引起混淆,不推荐使用
    enum Result {
      T,
      F = "不通过"
    }
    
    // 编译
    var Result;
    (function (Result) {
        Result[Result["T"] = 0] = "T";
        Result["F"] = "u4E0Du901Au8FC7";
    })(Result || (Result = {}));
    
    console.log(Result);
    { '0': 'T', T: 0, F: '不通过' }
    4、枚举成员的特性
    4-1、枚举成员的值不可修改
    Char.a = 6;  // Cannot assign to 'a' because it is a read-only property
     
    4-2、枚举成员的分类
    (1)、常量枚举:没有设置初始值,对已有枚举成员的引用,常量的表达式
    常量枚举成员会在编译时计算出结果,然后以常量的形式,出现在运行时环境
     
    (2)、需要计算的非常量表达式
    这些枚举成员的值不会在编译阶段计算,而是保留到程序的执行阶段
    enum Char {
      // 常量枚举成员
      a,
      b = Char.a,
      c = 1 + 3,
      // 非常量枚举成员
      d = Math.random(),
      e = 'hello'.length
    }
    
    console.log(Char);
    
    
    // 编译
    var Char;
    (function (Char) {
        // 常量枚举成员
        Char[Char["a"] = 0] = "a";
        Char[Char["b"] = 0] = "b";
        Char[Char["c"] = 4] = "c";
        // 非常量枚举成员
        Char[Char["d"] = Math.random()] = "d";
        Char[Char["e"] = 'hello'.length] = "e";
    })(Char || (Char = {}));
    
    
    // 运行
    { '0': 'b',
      '4': 'c',
      '5': 'e',
      a: 0,
      b: 0,
      c: 4,
      d: 0.5257674738591782,
      '0.5257674738591782': 'd',
      e: 5 }
    (3)、出现在非常量表达式后面的枚举成员必须要赋初始值,否则会报错(如下例中的 成员f )
    enum Char {
      // 常量枚举成员
      a,
      b = Char.a,
      c = 1 + 3,
      // 非常量枚举成员
      d = Math.random(),
      e = 'hello'.length,
      f // 枚举成员必须具有初始化表达式
    }
    5、常量枚举
    常量枚举是在 enum关键字前使用 const 修饰符
    特点:在编译阶段被移除
    作用:当我们不需要一个对象,而需要对象的值,就可以使用常量枚举,这样就可以避免在编译时生成多余的代码和间接引用
    const enum Month {
      Jan,
      Feb,
      Mar
    }
    
    // 编译时,没有任何输出
    
    console.log(Month);  // "const" 枚举仅可在属性、索引访问表达式、导入声明的右侧、导出分配或类型查询中使用。
    常量枚举成员在使用的地方被内联进来,且常量枚举不可能有计算成员
    const enum Directions {
      Up,
      Right,
      Down,
      Left
    }
    
    let directions = [Directions.Up, Directions.Right, Directions.Down, Directions.Left];
    
    // 编译
    var directions = [0 /* Up */, 1 /* Right */, 2 /* Down */, 3 /* Left */];
    
    console.log(directions);
    [ 0, 1, 2, 3 ]
    const enum Directions {
      Up,
      Right,
      Down,
      Left,
      UpRight = 3 + 1,
      RightDown = Directions.Right + 2,
      LeftDown = 9,
      // RightUp = 'hello'.length  // const enum member initializers can only contain literal values and other computed enum values
    }
    
    let directions = [
      Directions.Up, 
      Directions.Right, 
      Directions.Down, 
      Directions.Left, 
      Directions.UpRight,
      Directions.RightDown,
      Directions.LeftDown
    ];
    
    // 编译
    var directions = [
        0 /* Up */,
        1 /* Right */,
        2 /* Down */,
        3 /* Left */,
        4 /* UpRight */,
        3 /* RightDown */,
        9 /* LeftDown */
    ];
    
    console.log(directions);
    [ 0, 1, 2, 3, 4, 3, 9 ]

    6、在某些情况下,枚举和枚举成员都可以作为单独的类型存在

    enum E { a, b }
    enum F { a = 0, b = 1 }
    enum G { a = 'apple', b = 'banana' }
    
    let e: E = 4;
    let f: F = 4;
    // console.log(e === f);  // This condition will always return 'false' since the types 'E' and 'F' have no overlap.
    
    let e1: E.a = 3
    let e2: E.b = 3
    let e3: E.a = 3
    // console.log(e1 === e2);  // This condition will always return 'false' since the types 'E.a' and 'E.b' have no overlap
    console.log(e1 === e3);     // true
    
    let g1: G = G.a
    let g2: G.a = G.a
    console.log(g1 === g2);     // true
  • 相关阅读:
    a超链接设置样式
    return break continue的区别 js java
    mysql 约束
    JAVA中循环删除list中元素
    empty() 与 html("") 的区别
    java 各种数据类型判断为空
    bootstrap 栅栏系统
    height、clientHeight、offsetHeight、scrollHeight、height()、 innerHeight()、outerHeight()等的区别
    使用windos电脑模拟搭建集群(三)实现全网监控
    使用windos模拟搭建web集群(二)
  • 原文地址:https://www.cnblogs.com/rogerwu/p/12176596.html
Copyright © 2020-2023  润新知