JavaScript中定义枚举的语法是什么?
枚举或枚举类型是特殊的数据类型,它将变量设置为一组预定义的常量。在其他语言中,提供枚举数据类型以用于此应用程序。Javascript 本身不直接具有枚举类型,但我们可以通过 javascript 实现类似于枚举的类型。在本文中,我们将介绍在 javascript 中定义枚举类型的语法和用法。
以下语法显示了在 javascript 中枚举的基本实现,我们可以定义一个对象来封装枚举类型,并为每个枚举值分配键。
语法
const EnumType = { <enumConstant1> : <value1>, <enumConstant2> : <value2>, ... <enumConstantN> : <valueN> }
让我们来看一个例子,我们在这个例子中在 javascript 代码中使用带有整数值的枚举类型。
示例
<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 1, W: 2, N: 3, S: 4, NE: 31, NW: 32, SE: 41, SW: 42, } let myDirection = 41 if (myDirection === Direction.SE) { content += "Yes, your direction is South-East" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
此方法适用于小型代码库,但在某些情况下可能会产生一些歧义。例如,在下面的示例中,开发人员可能会将方向写成小写形式的第一个字母,但是字符串匹配失败并返回 false。
示例
<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 'East', W: 'West', N: 'North', S: 'South', NE: 'North-East', NW: 'North-West', SE: 'South-East', SW: 'South-West', } let myDirection = 'south-East' if (myDirection === Direction.SE) { content += "Yes, your direction is South-East" + '<br>' } else { content += "No, your direction is not South-East" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
开发人员还可以创建意外匹配的不相关枚举,因为它们只是两种原始类型的值,所以它们会被条件运算符匹配。让我们通过一个例子来看一下这个问题:
示例
<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 1, W: 2, N: 3, S: 4, NE: 31, NW: 32, SE: 41, SW: 42, } const Vehicle = { Bus: 1, Car: 2, Motorcycle: 3, Truck: 4 } if (Direction.S === Vehicle.Truck) { content += "Yes, your vehicle type is truck" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
在这个例子中,创建了两种不同的枚举类型,但在 if 块中检查它们的值时,它们却混淆了。这是不可取的。另一件事是使用整数或数字在语义上是不正确的。例如,方向不是整数或字符串,它们必须有自己的类型才能更好地表示。
使用 Symbol 类型的枚举
在 Javascript 中,有一个名为 Symbol() 的概念。符号不会相互冲突。因此,如果我们使用 Symbol 来定义值,它将更合适且更不容易出错。语法如下所示。
语法
const EnumType = { const EnumType = { <enumConstant1> : Symbol(<value1>), <enumConstant2> : Symbol(<value2>), ... <enumConstantN> : Symbol(<valueN>) }
让我们来看一个类似的例子,其中使用了 Symbol,让我们检查它们是否会冲突。
示例
<html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: Symbol(1), W: Symbol(2), N: Symbol(3), S: Symbol(4), NE: Symbol(31), NW: Symbol(32), SE: Symbol(41), SW: Symbol(42), } const Vehicle = { Bus: Symbol(1), Car: Symbol(2), Motorcycle: Symbol(3), Truck: Symbol(4), } if (Direction.S === Vehicle.Truck) { content += "Yes, your vehicle type is truck" + '<br>' } else { content += "Checking two dissimilar types." + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
创建不可变的枚举类型
到目前为止,我们已经看到了几种枚举的实现。但是,还有一些问题。在最后一种策略中,我们也可以通过为枚举类型赋值一个新值来更新它的值。为了限制枚举更新,我们可以通过将对象传递到 Object.freeze() 方法中来使其不可变。让我们通过一个例子来看一下。
语法
const EnumType = Object.freeze({ <enumConstant1> : Symbol(<value1>), <enumConstant2> : Symbol(<value2>), ... <enumConstantN> : Symbol(<valueN>) })
示例
<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: Symbol(1), W: Symbol(2), N: Symbol(3), S: Symbol(4), NE: Symbol(31), NW: Symbol(32), SE: Symbol(41), SW: Symbol(42), } content += "Value of SW: " + JSON.stringify(Direction.SE.toString()) + '<br>' Direction.SE = Symbol(50); // updating with a new value content += "Value of SW: " + JSON.stringify(Direction.SE.toString()) + '<br>' // creating an immutable object type const Vehicle = Object.freeze({ Bus: Symbol(1), Car: Symbol(2), Motorcycle: Symbol(3), Truck: Symbol(4), }) content += "Value of Car: " + JSON.stringify(Vehicle.Car.toString()) + '<br>' Vehicle.Car = Symbol(10); // updating will not affect the old value content += "Value of Car: " + JSON.stringify(Vehicle.Car.toString()) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
使用类的枚举
使用类定义枚举类型的最终方法。在类中,我们创建不同类别的静态成员,并为同一类的不同对象赋值,这些值通过构造函数传递。因此,当我们从外部使用它们时,可以使用类名和成员(枚举类型)名轻松地使用它们。让我们来看一个这个想法的例子。
示例
<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { class Vehicles { static Car = new Vehicles('car'); static Bus = new Vehicles('bus'); static Truck = new Vehicles('truck'); static Motorcycle = new Vehicles('motorcycle'); constructor(name) { this.name = name; } } let mot = Vehicles.Motorcycle; // mot is a vehicle of type motorcycle content += "Is mot a Vehicle enum? " + JSON.stringify(mot instanceof Vehicles) + '<br>' content += "Is 'motorcycle' string itself a Vehicle enum? " + JSON.stringify(Symbol('motorcycle') instanceof Vehicles) + '<br>' console.log('Type of mot: ', mot.constructor.name) content += 'Type of mot: ' + JSON.stringify(mot.constructor.name) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>
结论
枚举或 enum 数据类型用于创建有序的常量集,这些常量可用于我们的程序以提高其可读性。与其他语言不同,javascript 不原生支持枚举类型。有很多不同的方法可以在我们的 javascript 代码中设计枚举。基本枚举可以通过使用整数或字符串类型值的对象生成,但是这种方法不适用于许多这样的情况,例如,两个具有相同类型的枚举可能会发生冲突。可能的解决方案是使用 Symbol 来避免冲突。我们还可以使我们的枚举不可变以避免不必要的更新,最合适的方法是使用类作为枚举类型。