色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

Javascript Symbol原理及使用方法解析

瀏覽:71日期:2023-10-10 13:48:32

Symbol是ES6中新引入的一種基本數據類型,在此之前JavaScript中已有幾種基本數據類型:

Numberg String Boolean Null Undefined Object

不同于其他基本類型的通俗易懂,Symbol 是什么和有什么用一直有些讓人困惑。

什么是Symbol

JavaScript標準中規定對象的key只能是 String 或 Symbol 類型,區別在于 String 類型的key可以重復而 Symbol 類型的key是唯一的。Symbol 的本質是表示一個唯一標識。每次創建一個Symbol,它所代表的值都不可能重復,該值的內部實現可以視為一段數字(類似:3423498431987719455..)。所以理論上 Symbol 的存在只有一個意義:用于必須使用唯一值的場景。

創建Symbol

創建 Number、String等基本類型的實例有兩種方法:通過構造函數(或者叫工廠函數)和文字語法糖。比如:

// 構造函數const num = Number(3);const str = String(’hi’);

// 語法糖const num = 3;const str = ’hi’;

顯然使用語法糖更加簡潔。但是 Symbol 只能通過構造函數 Symbol() 進行創建:

const sym = Symbol();

或者,我們可以傳入一個字符串參數(descriptor)用于描述該Symbol:

const sym = Symbol(’cat’);

注意:傳入的參數對 Symbol 值的產生并無影響,因為就算每次傳入的參數都一樣,生成的Symbol值也是不等的。該參數的作用僅用于描述被創建的Symbol,以便debug時可以識別出Symbol的含義。 所以,下列等式結果為 false:

Symbol(’cat’) === Symbol(’cat’) // falseSymbol.for(key)

和 Symbol() 類似,Symbol.for(key) 也可以創建一個Symbol,不一樣的是:創建的 Symbol 是全局的(在全局Symbol表中注冊),而如果全局已經存在相同 key 的Symbol,則直接返回該Symbol。所以,下列等式結果為 true:

Symbol.for(’cat’) === Symbol.for(’cat’) // true

如何使用Symbol

其實 Symbol 本身很簡單,但是如何把它用好、且用的恰到好處卻使人困惑,因為在平常工作中并沒有多少非Symbol不用的場景。但是用對了Symbol會對你的代碼質量有不少提升。來看下面幾種案例:

1. 用作對象的key,防止命名沖突

使用Symbol作為Object的key,可以保證和其他key都不重復。因此,Symbol非常適合用于對對象的屬性進行拓展。

比如,當使用 String 作為對象的key時,一旦出現重復的key則后面的屬性會覆蓋前面的:

const persons = { ’bruce’: ’wayne’, ’bruce’: ’banner’}console.log(persons.bruce); // ’wayne’使用Symbol作為Key可以避免這種情況:const bruce1 = Symbol(’bruce’);const bruce2 = Symbol(’bruce’);const persons = { [bruce1]: ’wayne’, [bruce2]: ’banner’}console.log(persons[bruce1]); // ’wayne’console.log(persons[bruce2]); // ’banner’

js很多內建的方法都是通過 Symbol 進行指定的,比如:Symobol.iterator 指定了一個iterable對象的迭代器方法;Symbol.replace 指定了對象字符串替換的方法,這類 Symbol 被稱為 Well-know Symbols,代表了js語言的內部行為。

2. 使用Symbol定義枚舉

由于Javascript并不自帶枚舉類型,通常情況下我們會使用一個freezed的Object來模擬枚舉類型,比如定義一個日期的枚舉:

const DAYS = Object.freeze({monday: 1,tuesday: 2,wednesday: 3});

此時有一個方法,接收 DAYS 的枚舉值來返回當天要做的事:

function getTodo(day) { switch (day) { case DAYS.monday: return '看電影'; case DAYS.tuesday: return '購物'; case DAYS.wednesday: return '健身'; default: return '日期錯誤'; }}

我們希望代碼邏輯足夠嚴謹,傳入的參數嚴格按照 DAYS.monday 的形式,否則就返回日期錯誤,但是該枚舉類型的實現卻做不到。比如:getTodo(1) 依然能得到 “看電影” 這個結果。

但是使用Symbol卻可以解決這一問題,DAYS 枚舉類型可以重新定義為:

const DAYS = Object.freeze({monday: Symbol(’monday’),tuesday: Symbol(’tuesday’),wednesday: Symbol(’wednesday’)});

此時 getTodo 方法必須接收 DAYS.monday 這樣的枚舉值作為參數,否則就返回 “日期錯誤”,因為世界上再沒有任何一個值和 DAYS.monday 相等了。

這樣定義枚舉顯然更嚴謹了。

3. 使用Symbol存儲元數據

Key為Symbol類型的屬性是不能被枚舉的,這是 Symbol 除了唯一性外的第二大特性,因此使用for...in,Object.keys()、Object.hasOwnProperty()等方法不能識別Symbol屬性,簡而言之Symbol屬性對用戶是“隱藏”的(但并不是private的,因為有其他途徑可以獲取Symbol屬性),例如:

Javascript Symbol原理及使用方法解析

因此Symbol作為“隱藏”屬性可以用來存儲對象的元數據。比如,有一個 TodoList:

class TodoList { constructor() { // todo數量 this.count = 0; } // 增加todo add(id, content) { this[id] = content; this.count++; }}const list = new TodoList();

我們使用 add() 方法向其中增加幾個todo:

list.add(’a’, ’看電影’);list.add(’b’, ’購物’);list.add(’c’, ’健身’);

當我們想使用 for...in 查看里面所有的todo時,會把 count 屬性也帶出來:

Javascript Symbol原理及使用方法解析

為了隱藏count屬性,更方便的對todo進行操作,我們可以使用Symbol來存儲它,TodoList 類修改為:

const count = Symbol(’count’);class TodoList {constructor() {this[count] = 0;}

add(id, content) {this[id] = content;this[count]++;}}

當我們再遍歷 TodoList 的時候,count就隱藏了:

Javascript Symbol原理及使用方法解析

當我們想獲取存儲在Symbol中的原數據時,可以使用 Object.getOwnPropertySymbols() 方法:

Javascript Symbol原理及使用方法解析

以上是我能想到的 Symbol 的用途,如果大家有其他心得體會歡迎補充。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 国产成人精品免费视频大 | 一区二区日韩欧美 | 91精品成人 | 青青自拍视频一区二区三区 | 欧美日韩一区二区高清视 | 福利片成人午夜在线 | 欧美性毛片大片 | 久久福利青草精品资源站 | 欧美黑大粗硬毛片视频 | 久久精品中文字幕不卡一二区 | 免费韩国美女爽快一级毛片 | 成人永久免费视频网站在线观看 | 91久久亚洲国产成人精品性色 | 午夜影院亚洲 | 日韩美视频网站 | 久久精品a| 99久在线观看 | 国产精品资源手机在线播放 | 亚洲国产成人久久综合一区 | 免费观看性欧美大片无片 | 欧美成人免费网在线观看 | 亚洲国产成人久久综合一 | 黄 色 成 年 人小说 | 亚洲天堂网在线视频 | 成人在线免费播放 | 国产盗摄精品一区二区三区 | 欧美做爰孕妇群 | 亚洲欧美另类在线视频 | 日本欧美大片 | 99爱在线精品视频免费观看9 | 欧美手机手机在线视频一区 | 手机在线观看一级午夜片 | 国产午夜毛片v一区二区三区 | 99久久精品免费看国产一区二区三区 | 欧美一级片播放 | 欧美综合在线观看 | 三级全黄视频 | 一级做人爱a视频正版免费 一级做性色a爱片久久片 | 久久久久国产成人精品亚洲午夜 | 毛片高清一区二区三区 | 国产乱弄视频在线观看 |