欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TypeScript魔法堂之枚舉的超實用手冊

 更新時間:2020年10月29日 14:32:26   作者:^_^肥仔John  
這篇文章主要介紹了TypeScript魔法堂之枚舉的超實用手冊,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

也許前端的同學(xué)會問JavaScript從誕生至今都沒有枚舉類型,我們不是都活得挺好的嗎?為什么TypeScript需要引入枚舉類型呢?

也許被迫寫前端的后端同學(xué)會問,TypeScript的枚舉類型是和Java/.NET的一樣嗎?
下面我們來一起探討和嘗試解答吧!

前端一直都需要枚舉

我敢保證,前端的同學(xué)都會萬分肯定地告訴大家:我們從來沒有寫過枚舉。那是因為雖然ECMAScript將enum作為保留字,但至ES2020為止還沒有提出枚舉的實現(xiàn)規(guī)范。語言沒有提供規(guī)范和語言實現(xiàn),不代表思想活躍勇于造輪子的程序員們不會自己擼一個。
如果語言沒有提供,還有那么毅然決然要自己造一個,那枚舉到底能解決我們什么問題呢?

枚舉真的有點(diǎn)用

首先,枚舉字面上的意思就遍歷一個存在若干個的值有窮集合的所有成員。核心有兩點(diǎn):

  1. 有窮集合;
  2. 遍歷。

也就是說,只要我們需要表示某個變量的值必須為某個有窮集合的成員時,我們是怎么也繞不開枚舉的。

寫個JavaScript版本的枚舉

下面是剛好滿足大部分業(yè)務(wù)需求的枚舉實現(xiàn):

class Color {
 // tricky:自增枚舉成員值
 static counter = null
 
 // 枚舉成員
 static Red = new Color('Red')
 static Green = new Color('Green')
 
 // 反向映射
 static valueOf(value) {
 for (var name in Color) {
  if (!(name in Color.prototype) && Color[name].value === value) {
  return Color[name]
  }
 }
 }
    
 constructor(name, value){
        if ('counter' in Color);else return

 this.name = name
 if (value == null) {
  if (Color.counter === null) {
  this.value = Color.counter = 0
  }
  else {
  this.value = ++Color.counter
  }
 }
 else {
  this.value = Color.counter = value
 }
 }
 
 toString() {
 return `Color.${this.name}`
 }
}
delete Color.counter
Object.freeze(Color) // tricky:禁止在定義之外的位置修改枚舉成員

其實我們只想表達(dá)某些變量將以含有Red、Green兩個成員的Color有窮集合作為值域而已,卻要寫這么多語義無關(guān)的代碼(嚴(yán)格遵循“能寫hi絕對不寫hello”原則)。而且在一般規(guī)模的項目當(dāng)中,往往不止一個枚舉類型,復(fù)制粘貼確實可以解決問題,但真心不優(yōu)雅。

而TypeScript內(nèi)置枚舉的語言實現(xiàn)恰恰能解決這個問題。

TypeScript的枚舉和后端的真不一樣

后端的同學(xué)對枚舉絕對是不會陌生的(除非是Pyton/Nodejs后端的同學(xué)啦),雖然TypeScript是JavaScript的超集,但最終需要編譯為JavaScript代碼,并且要兼容現(xiàn)有JavaScript庫,所以確實無法和后端的枚舉類型一模一樣。
所以我還是建議大家運(yùn)用空杯心理,重頭理解TypeScript的枚舉類型,將過去的知識作為助燃劑,而不是圍欄更適宜。

數(shù)字枚舉類型和字符串枚舉類型

TypeScript官網(wǎng)教程已經(jīng)對枚舉類型進(jìn)行了詳細(xì)的講解說明,我認(rèn)為最核心是理解清楚其分為兩大類:

數(shù)字枚舉類型

enum Response {
  No = 0, // 手動設(shè)置初始化器
  Yes = // 附加默認(rèn)的支持自動增長的初始化器,因此Yes的值為1
}

特性為:
1.1. 枚舉成員附帶默認(rèn)的初始化器;
1.2. 初始化器支持自動增長;
1.3. 支持反向映射。(注意:這里是反向映射,而不是通過值轉(zhuǎn)換為枚舉成員)

字符串枚舉類型

enum Color {
 Red = 'Red',
 Green = 'Green',
}

特性為:
1.1. 必須為枚舉成員設(shè)置初始化器;
1.2. 初始化器不支持自動增長;
1.3. 不支持反向映射。

而計算和常量成員其實就是上述兩種枚舉類型中初始化器的細(xì)分特性罷了。

enum讓數(shù)字枚舉類型反向映射成為可能

上一節(jié)介紹到數(shù)字枚舉類型支持反向映射,但前提是通過enum定義的數(shù)字枚舉類型才支持。那是因為enum Respose {No,Yes,}最終會被編譯為如下JavaScript代碼:

var Response;
(function (Response) {
  Response[Response["No"] = 0] = "No";
  Response[Response["Yes"] = 1] = "Yes";
})(Response || (Response = {}));

那么我們就可以通過Response[0]反向映射得到"No"。
但對于字符串枚舉類型就沒有這種好事了,看看enum Color {Red='Red',Green='Green',}編譯出來的代碼吧

var Color;
(function (Color) {
  Color["Red"] = "Red";
  Color["Green"] = "Green";
})(Color || (Color = {}));

只能說非常樸實無華,就這樣沒啥好說的,大家在使用時注意差異就好了。

const enum高效的編譯時內(nèi)聯(lián)

官方文檔明確寫出“大多數(shù)情況下,枚舉是十分有效的方案。 然而在某些情況下需求很嚴(yán)格。 為了避免在額外生成的代碼上的開銷和額外的非直接的對枚舉成員的訪問,我們可以使用 const枚舉”,那是為什么呢?
那是因為通過const enum定義的編譯時枚舉類型,效果和通過C/C++的#define定義常量沒實質(zhì)區(qū)別。說白了就是假如僅僅通過通過const enum定義了枚舉類型而沒有其它地方調(diào)用,這段代碼將在編譯時被直接抹掉。
當(dāng)其它地方調(diào)用該枚舉類型時,將直接把枚舉類型成員的值內(nèi)聯(lián)到使用處,如下:

const enum Response {
  No,
  Yes,
}

console.log(Response.NO, Response.Yes)

編譯后成為console.log(0, 1),運(yùn)行效果自然只能比enum定義的好。

什么時候用enum?又在什么場景下用const enum呢?

先說說結(jié)論:

使用enum的場景:
1.1. 需要使用反向映射時;
1.2. 需要編譯后的JavaScript代碼保留對象.屬性或?qū)ο骩屬性]形式時。

使用const enum的場景:能不用enum時就用const enum(哈哈!)
使用enum的場景中的第一條還很好理解,但第二條是啥回事呢?我這里有個真實發(fā)生的示例,可以讓大家更好的理解:
背景:為Photoshop的ExtendScript編寫類型聲明。
需求:DialogModes.NO在ExtendScript中返回值為DialogModes.No本身,編譯后的JavaScript中必須保留DialogModes.NO的代碼形式。

那么又為何鼓勵大家能用const enum時就用const enum呢?
這是TypeScript為大家特意準(zhǔn)備的編譯時優(yōu)化方式,好東西為啥不用呢?編譯時優(yōu)化難道不香嗎?

外部枚舉declare enum的作用?

所謂外部枚舉,即使我們?yōu)榱嗽赥ypeScript開發(fā)環(huán)境下,更好地使用某些已采用JavaScript編寫的庫,而被迫為其編寫的枚舉類型聲明。
如ExtendScript標(biāo)準(zhǔn)庫存在枚舉DialogModes.NO,DialogModes.YES,DialogModes.ALL。于是在.d.ts文件中編寫如下外部枚舉類型聲明

declare enum DialogModes {
  NO,
  YES,
  ALL,
}

總結(jié)

對于日常開發(fā)中我們繞不過枚舉類型,TypeScript為我們提供語言實現(xiàn)和編譯時優(yōu)化,除了保護(hù)了我們?yōu)槿绾蝺?yōu)化實現(xiàn)枚舉類型而日思夜想導(dǎo)致日漸稀疏的頭發(fā)外,還大大降低了因復(fù)制粘貼帶來的代碼庫體積徒增的風(fēng)險。

到此這篇關(guān)于TypeScript魔法堂之枚舉的超實用手冊的文章就介紹到這了,更多相關(guān)TypeScript 枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js實現(xiàn)拖拽效果(構(gòu)造函數(shù))

    js實現(xiàn)拖拽效果(構(gòu)造函數(shù))

    這篇文章主要介紹了js利用構(gòu)造函數(shù)實現(xiàn)拖拽效果
    2015-12-12
  • 小程序雙頭slider選擇器的實現(xiàn)示例

    小程序雙頭slider選擇器的實現(xiàn)示例

    這篇文章主要介紹了小程序雙頭slider選擇器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • LayUI+Shiro實現(xiàn)動態(tài)菜單并記住菜單收展的示例

    LayUI+Shiro實現(xiàn)動態(tài)菜單并記住菜單收展的示例

    這篇文章主要介紹了LayUI+Shiro實現(xiàn)動態(tài)菜單并記住菜單收展的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 純js實現(xiàn)輪播圖效果

    純js實現(xiàn)輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了純js實現(xiàn)輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • JavaScript代碼實現(xiàn)禁止右鍵、禁選擇、禁粘貼、禁shift、禁ctrl、禁alt

    JavaScript代碼實現(xiàn)禁止右鍵、禁選擇、禁粘貼、禁shift、禁ctrl、禁alt

    這篇文章主要介紹了JavaScript代碼實現(xiàn)禁止右鍵、禁選擇、禁粘貼、禁shift、禁ctrl、禁alt,需要的朋友可以參考下
    2015-11-11
  • javascript正則表達(dá)配置擴(kuò)展名并實現(xiàn)驗證

    javascript正則表達(dá)配置擴(kuò)展名并實現(xiàn)驗證

    這篇文章主要介紹了javascript正則表達(dá)配置擴(kuò)展名并實現(xiàn)驗證,文章圍繞主題展開相關(guān)資料,具有以得參考價值,需要的小伙伴可以參考一下
    2022-02-02
  • JavaScript實現(xiàn)換膚功能

    JavaScript實現(xiàn)換膚功能

    js換膚功能的實現(xiàn)原理非常簡單,就是使用js切換對應(yīng)的css樣式表文件,本文重點(diǎn)給大家介紹JavaScript實現(xiàn)換膚功能,感興趣的朋友參考下吧
    2017-09-09
  • 使用Electron自制錄屏軟件

    使用Electron自制錄屏軟件

    錄屏軟件對于我們來說都不陌生了,本文我們要做的事情是實現(xiàn)自己的錄屏軟件,載體使用Electron,因為它更適合錄制桌面的場景,下面我們就來看看具體實現(xiàn)方法吧
    2024-01-01
  • 微信小程序地圖繪制線段并且測量(實例代碼)

    微信小程序地圖繪制線段并且測量(實例代碼)

    這篇文章主要介紹了微信小程序地圖繪制線段并且測量,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 前端常用的js函數(shù)方法

    前端常用的js函數(shù)方法

    這篇文章主要給大家分享的是常用的js函數(shù)的方法,告別搜索引擎的幫助,提高你的開發(fā)效率,,需要的朋友可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2021-12-12

最新評論