TypeScript学习-枚举

作者: JsForLife | 来源:发表于2019-06-10 00:10 被阅读0次

    本篇文章将讲枚举类型的基础知识,枚举与哈希,集合这三者的区别以及各自合适用的场景。

    枚举

    枚举常用于定义一些带名字的常量,枚举内的数据项类型可为number或string。

    数字枚举

    声明数字枚举的语法如下:

    // 在没指定首项的值的情况下,默认首的值为0,往后每项加1
    enum NumberList {
      first,     // 0
      second,    // 1
      third,     // 2
    }
    
    // 在值指定首项的值的情况下,以首项的值为起始值,往后每项加1
    enum NumberList {
      first = 1, // 1
      second,    // 2
      third,     // 3
    }
    
    // 使用也很简单,在定函数参数时,把枚举作为参数类型
    function log_number(param:NumberList) {
      console.log(param);
    }
    
    // 传入枚举的某一项
    log_number(NumberList.first);
    

    字符串枚举

    字符串枚举就是数据项都是string的枚举,它不存在数字枚举的自增长行为,需要每项都赋值

    enum Directions {
      east = 'east',
      south = 'south',
      west = 'west',
      north = 'north',
    }
    

    异构枚举

    同时拥有number和string类型的数据项的枚举

    enum Mix {
      first = 1,
      second = 'second',
    }
    

    计算值和常量

    你可以将一些表达式或常量赋值给枚举的项,ts会在编译过程中算出表达式的结果(结果必须是number或string,否则报错),并赋值给项。

    const num = 3;
    function get_number() {
      return 2;
    }
    
    enum ComputedEnum {
      first,                    // 0
      second = get_number(),    // 2
      third = num,              // 4
      fourth = 1 << 2,          // 3
      fifth = 'fifth'.length,   // 5
    }
    
    // 若在非末项使用了表达式,则随后的项得赋值,否则报错
    enum NumberList {
      first,                  // 0
      second = get_number(),  // 2
      third,                  // 报错,值无法推断,得赋一个值   
    }
    
    // 在字符串枚举中不能使用
    enum Mix {
      first = '',
      second = get_number(),  //报错
    }
    

    反向映射

    枚举编译成es5后,其实就是个对象,保存了“键-值”的映射关系,而创建数字枚举时,数字枚举内还会多生成一个“值-键”的映射。

    enum NumberList {
      first,    
      second, 
      third,
    }
    

    以上代码编译成es5后如下所示:

    var NumberList;
    (function (NumberList) {
        NumberList[NumberList["first"] = 0] = "first";
        NumberList[NumberList["second"] = 1] = "second";
        NumberList[NumberList["third"] = 2] = "third";
    })(NumberList || (NumberList = {}));
    

    等价于

    var NumberList;
    (function (NumberList) {
        // 原映射
        NumberList["first"] = 0;
        NumberList["second"] = 1
        NumberList["third"] = 2;
        
        // 反向映射
        NumberList[0] = "first";
        NumberList[1] = "second";
        NumberList[2] = "third";
    })(NumberList || (NumberList = {}));
    

    const 枚举
    正如上面说的,枚举编译后会生成一个保存映射关系的对象。有时候,为了节省这部分开销,常量枚举在编译的时候,枚举内的变量会被内联到调用方内,而不保留常量枚举。

    const enum NumberList {
      first,    
      second, 
      third,
    }
    
    const arr = [NumberList.first, NumberList.second, NumberList.third];
    

    上述的代码编译后,只留下了引用枚举变量的数组

    const array = [0 /* first */, 1 /* second */, 2 /* third */];
    

    枚举,哈希,集合

    枚举(enum):有键值对(映射数字枚举还有反向映射),不可遍历,声明以后不可修改;
    哈希(object和map):有键值对,可遍历,声明后可修改;
    集合(set):只有键(或者说只有值也OK),可遍历,声明后可修改;
    以上每个数据类型的键都是唯一的。

    各自的应用场景

    定义一组常量用枚举,不像map和set那样存在被修改的风险。
    函数处理过程中产生的中间变量用map,譬如拼接数据:

    const user_hash:any= {};
    const user_infos = [{user_id:1, name:'one'}, {user_id:2, name:'two'}, {user_id:3, name:'three'}];
    const user_class = [{user_id:1, subject:'English'}, {user_id:2, subject:'Math'}, {user_id:3, subject:'Chinese'}];
    
    for (const item of user_infos) {
      user_hash[item.user_id] = item;
    }
    
    for (const item of user_class) {
      const { user_id } = item;
      user_hash[user_id] = { ...item, ...user_hash[user_id] };
    }
    

    判断数据是否存在某个结果集内,或做去重,用set:

    // 预设可选的科目和上课时间
    const subject_set = new Set(['English', 'Math']);
    const class_day_set = new Set(['Saturday', 'Sunday']);
    
    // 假设这是前端传来的参数
    const request_body = {
      subject: 'English',
      class_day: 'Monday',
    };
    
    // 校验参数是否合法
    subject_set.has(request_body.class_day);  // true
    class_day_set.has(request_body.subject);  // false
    
    // 用set的key唯一性实现数组去重
    const array1 = [1, 2, 3];
    const array2 = [3, 4, 5];
    const set = new Set(array1.concat(array2));
    const array = [...set];  // [1, 2, 3, 4, 5, 6];
    

    相关文章

      网友评论

        本文标题:TypeScript学习-枚举

        本文链接:https://www.haomeiwen.com/subject/avtwtctx.html