javascript中的创建枚举四种方式-kb88凯时官网登录

来自:网络
时间:2023-05-17
阅读:
免费资源网 - https://freexyz.cn/
目录

字符串和数字具有无数个值,而其他类型如布尔值则是有限的集合。

一周的日子(星期一,星期二,...,星期日),一年的季节(冬季,春季,夏季,秋季)和基本方向(北,东,南,西)都是具有有限值集合的例子。

当一个变量有一个来自有限的预定义常量的值时,使用枚举是很方便的。枚举使你不必使用魔法数字和字符串(这被认为是一种反模式)。

让我们看看在javascript中创建枚举的四种好方法(及其优缺点)。

基于对象的枚举

枚举是一种数据结构,它定义了一个有限的具名常量集。每个常量都可以通过其名称来访问。

让我们来考虑一件t恤衫的尺寸:smallmedium,和large

在javascript中创建枚举的一个简单方法(虽然不是最理想的)是使用一个普通的javascript对象。

const sizes = {
  small: 'small',
  medium: 'medium',
  large: 'large',
}
const mysize = sizes.medium
console.log(mysize === sizes.medium) // logs true

sizes是一个基于javascript对象的枚举,它有三个具名常量:sizes.smallsizes.medium以及sizes.large

sizes也是一个字符串枚举,因为具名常量的值是字符串:'small' ,'medium',以及 'large'

javascript中的创建枚举四种方式

要访问具名常量值,请使用属性访问器。例如,sizes.medium的值是'medium'

枚举的可读性更强,更明确,并消除了对魔法字符串或数字的使用。

优缺点

普通的对象枚举之所以吸引人,是因为它很简单:只要定义一个带有键和值的对象,枚举就可以了。

但是在一个大的代码库中,有人可能会意外地修改枚举对象,这将影响应用程序的运行。

const sizes = {
  small: 'small',
  medium: 'medium',
  large: 'large',
}
const size1 = sizes.medium
const size2 = sizes.medium = 'foo' // changed!
console.log(size1 === sizes.medium) // logs false

sizes.medium 枚举值被意外地改变。

size1,虽然被初始化为sizes.medium,但不再等同于sizes.medium

普通对象的实现没有受到保护,因此无法避免这种意外的改变。

让我们仔细看看字符串和symbol枚举。以及如何冻结枚举对象以避免意外改变的问题。

枚举值类型

除了字符串类型,枚举值可以是一个数字:

const sizes = {
  small: 0,
  medium: 1,
  large: 2
}
const mysize = sizes.medium
console.log(mysize === sizes.medium) // logs true

上述例子中,sizes枚举是数值枚举,因为值都是数字:0,1,2。

你也可以创建symbol枚举:

const sizes = {
  small: symbol('small'),
  medium: symbol('medium'),
  large: symbol('large')
}
const mysize = sizes.medium
console.log(mysize === sizes.medium) // logs true

使用symbol的好处是,每个symbol都是唯一的。这意味着,你总是要通过使用枚举本身来比较枚举:

const sizes = {
  small: symbol('small'),
  medium: symbol('medium'),
  large: symbol('large')
}
const mysize = sizes.medium
console.log(mysize === sizes.medium)     // logs true
console.log(mysize === symbol('medium')) // logs false

使用symbol枚举的缺点是json.stringify()symbol字符串化为nullundefined,或者跳过有symbol作为值的属性:

const sizes = {
  small: symbol('small'),
  medium: symbol('medium'),
  large: symbol('large')
}
const str1 = json.stringify(sizes.small)
console.log(str1) // logs undefined
const str2 = json.stringify([sizes.small])
console.log(str2) // logs '[null]'
const str3 = json.stringify({ size: sizes.small })
console.log(str3) // logs '{}'

在下面的例子中,我将使用字符串枚举。但是你可以自由地使用你需要的任何值类型。

如果你可以自由选择枚举值类型,就用字符串吧。字符串比数字和symbol更容易进行调试。

基于object.freeze()枚举

保护枚举对象不被修改的一个好方法是冻结它。当一个对象被冻结时,你不能修改或向该对象添加新的属性。换句话说,这个对象变成了只读。

在javascript中,object.freeze()工具函数可以冻结一个对象。让我们来冻结sizes枚举:

const sizes = object.freeze({
  small: 'small',
  medium: 'medium',
  large: 'large',
})
const mysize = sizes.medium
console.log(mysize === sizes.medium) // logs true

const sizes = object.freeze({ ... }) 创建一个冻结的对象。即使被冻结,你也可以自由地访问枚举值: const mysize = sizes.medium

优缺点

如果一个枚举属性被意外地改变了,javascript会抛出一个错误(在严格模式下):

const sizes = object.freeze({
  small: 'small',
  medium: 'medium',
  large: 'large',
})
const size1 = sizes.medium
const size2 = sizes.medium = 'foo' // throws typeerror

语句const size2 = sizes.medium = 'foo' 对 sizes.medium 属性进行了意外的赋值。

因为sizes是一个冻结的对象,javascript(在严格模式下)会抛出错误:

typeerror: cannot assign to read only property 'medium' of object

网站地图