- TypeScript入門與實戰
- 鐘勝平編著
- 1540字
- 2021-01-15 15:36:11
5.4.5 常量枚舉成員與計算枚舉成員
每個枚舉成員都有一個值,根據枚舉成員值的定義可以將枚舉成員劃分為以下兩類:
?常量枚舉成員
?計算枚舉成員
5.4.5.1 常量枚舉成員
若枚舉類型的第一個枚舉成員沒有定義初始值,那么該枚舉成員是常量枚舉成員并且初始值為0。示例如下:
01 enum Foo { 02 A, // 0 03 }
此例中,枚舉成員A是常量枚舉成員,并且“Foo.A”的值為0。
若枚舉成員沒有定義初始值并且與之緊鄰的前一個枚舉成員值是數值型常量,那么該枚舉成員是常量枚舉成員并且初始值為緊鄰的前一個枚舉成員值加1。如果緊鄰的前一個枚舉成員的值不是數值型常量,那么將產生錯誤。示例如下:
01 enum Foo { 02 A, // 0 03 B, // 1 04 } 05 06 enum Bar { 07 C = 'C', 08 D, // 編譯錯誤 09 }
此例中,枚舉成員“Foo.A”和“Foo.B”都是常量枚舉成員。枚舉成員“Bar.D”的定義將產生編譯錯誤,因為它沒有指定初始值并且前一個枚舉成員“Bar.C”的值不是數值。
若枚舉成員的初始值是常量枚舉表達式,那么該枚舉成員是常量枚舉成員。常量枚舉表達式是TypeScript表達式的子集,它能夠在編譯階段被求值。常量枚舉表達式的具體規則如下:
?常量枚舉表達式可以是數字字面量、字符串字面量和不包含替換值的模板字面量。
?常量枚舉表達式可以是對前面定義的常量枚舉成員的引用。
?常量枚舉表達式可以是用分組運算符包圍起來的常量枚舉表達式。
?常量枚舉表達式中可以使用一元運算符“+”“-”“~”,操作數必須為常量枚舉表達式。
?常量枚舉表達式中可以使用二元運算符“+”“-”“*”“**”“/”“%”“<<”“>>”“>>>”“&”“|”“^”,兩個操作數必須為常量枚舉表達式。
例如,下例中的枚舉成員均為常量枚舉成員:
01 enum Foo { 02 A = 0, // 數字字面量 03 B = 'B', // 字符串字面量 04 C = `C`, // 無替換值的模板字面量 05 D = A, // 引用前面定義的常量枚舉成員 06 } 07 08 enum Bar { 09 A = -1, // 一元運算符 10 B = 1 + 2, // 二元運算符 11 C = (4 / 2) * 3, // 分組運算符(小括號) 12 }
字面量枚舉成員是常量枚舉成員的子集。字面量枚舉成員是指滿足下列條件之一的枚舉成員,具體條件如下:
?枚舉成員沒有定義初始值。
?枚舉成員的初始值為數字字面量、字符串字面量和不包含替換值的模板字面量。
?枚舉成員的初始值為對其他字面量枚舉成員的引用。
下例中,Foo枚舉的所有成員都是字面量枚舉成員,同時它們也都是常量枚舉成員:
01 enum Foo { 02 A, 03 B = 1, 04 C = -3, 05 D = 'foo', 06 E = `bar`, 07 F = A 08 }
5.4.5.2 計算枚舉成員
除常量枚舉成員之外的其他枚舉成員都屬于計算枚舉成員。下例中,枚舉成員“Foo.A”和“Foo.B”均為計算枚舉成員:
01 enum Foo { 02 A = 'A'.length, 03 B = Math.pow(2, 3) 04 }
5.4.5.3 使用示例
枚舉表示一組有限元素的集合,并通過枚舉成員名來引用集合中的元素。有時候,程序中并不關注枚舉成員值。在這種情況下,讓TypeScript去自動計算枚舉成員值是很方便的。示例如下:
01 enum Direction { 02 Up, 03 Down, 04 Left, 05 Right, 06 } 07 08 function move(direction: Direction) { 09 switch (direction) { 10 case Direction.Up: 11 console.log('Up'); 12 break; 13 case Direction.Down: 14 console.log('Down'); 15 break; 16 case Direction.Left: 17 console.log('Left'); 18 break; 19 case Direction.Right: 20 console.log('Right'); 21 break; 22 } 23 } 24 25 move(Direction.Up); // 'Up' 26 move(Direction.Down); // 'Down'
程序不依賴枚舉成員值時,能夠降低代碼耦合度,使程序易于擴展。例如,我們想給Direction枚舉添加一個名為None的枚舉成員來表示未知方向。按照慣例,None應作為第一個枚舉成員。因此,我們可以將代碼修改如下:
01 enum Direction { 02 None, 03 Up, 04 Down, 05 Left, 06 Right, 07 } 08 09 function move(direction: Direction) { 10 switch (direction) { 11 case Direction.None: 12 console.log('None'); 13 break; 14 case Direction.Up: 15 console.log('Up'); 16 break; 17 case Direction.Down: 18 console.log('Down'); 19 break; 20 case Direction.Left: 21 console.log('Left'); 22 break; 23 case Direction.Right: 24 console.log('Right'); 25 break; 26 } 27 } 28 29 move(Direction.Up); // 'Up' 30 move(Direction.Down); // 'Down' 31 move(Direction.None); // 'None'
此例中,枚舉成員Up、Down、Left和Right的值已經發生了改變,Up的值由0變為1,以此類推。由于move()函數的行為不直接依賴枚舉成員的值,因此本次代碼修改對move()函數的已有功能不產生任何影響。但如果程序中依賴了枚舉成員的具體值,那么這次代碼修改就會破壞現有的代碼,如下所示:
01 enum Direction { 02 None, 03 Up, 04 Down, 05 Left, 06 Right, 07 } 08 09 function move(direction: Direction) { 10 switch (direction) { 11 // 不會報錯,但是邏輯錯誤,Direction.Up的值已經不是數字0 12 case 0: 13 console.log('Up'); 14 break; 15 16 // 省略其他代碼 17 } 18 }
- Ceph Cookbook
- Learning OpenStack Networking(Neutron)
- Learning Laravel's Eloquent
- Create React App 2 Quick Start Guide
- ASP.NET開發與應用教程
- OpenGL Data Visualization Cookbook
- Azure Serverless Computing Cookbook
- Java RESTful Web Service實戰
- Mastering Unreal Engine 4.X
- Flutter之旅
- Mastering R for Quantitative Finance
- JavaScript重難點實例精講
- Android Application Programming with OpenCV 3
- Unreal Engine 4 Game Development Essentials
- 米思齊實戰手冊:Arduino圖形化編程指南