TypeScript扫盲TypeScript基础Learning Typescript

TypeScript学习-枚举

2019-06-10  本文已影响0人  JsForLife

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

枚举

枚举常用于定义一些带名字的常量,枚举内的数据项类型可为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];
上一篇 下一篇

猜你喜欢

热点阅读