【ES6(2015)】Symbol
文章目錄
- 1. 聲明方式
- 2. Symbol.for()
- 3. Symbol.keyFor()
- 4. 作為屬性名
- 5. 屬性遍歷
- 6. 消除魔術字符串
ES6 引入了一種新的原始數據類型 Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。
Symbol 值通過Symbol函數生成。這就是說,對象的屬性名現在可以有兩種類型,一種是原來就有的字符串,另一種就是新增的 Symbol 類型。凡是屬性名屬于 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產生沖突。
1. 聲明方式
let s = Symbol()typeof s // "symbol"變量s就是一個獨一無二的值。typeof的結果說明s是 Symbol 數據類型。
既然是獨一無二的,那么兩個Symbol()就一定是不相等的:
let s1 = Symbol() let s2 = Symbol() console.log(s1) console.log(s2) console.log(s1 === s2) // falseSymbol函數前不能使用new命令,否則會報錯。這是因為生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由于 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似于字符串的數據類型。
Symbol函數可以接受一個字符串作為參數,表示對 Symbol 實例的描述,主要是為了在控制臺顯示,或者轉為字符串時,比較容易區分。
let s1 = Symbol('foo') let s2 = Symbol('foo') console.log(s1) console.log(s2) console.log(s1 === s2) // falseconsole.log(s1.description) // foo 獲取描述2. Symbol.for()
Symbol.for()接受一個字符串作為參數,然后搜索有沒有以該參數作為名稱的 Symbol值。如果有,就返回這個 Symbol值,否則就新建一個以該字符串為名稱的Symbol 值,并將其注冊到全局。
let s1 = Symbol.for('foo') let s2 = Symbol.for('foo') console.log(s1 === s2) // trueSymbol.for()與Symbol()這兩種寫法,都會生成新的 Symbol。它們的區別是,前者會被登記在全局環境中供搜索,后者不會。Symbol.for()不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key是否已經存在,如果不存在才會新建一個值。
3. Symbol.keyFor()
Symbol.keyFor()方法返回一個全局已登記的 Symbol類型值的key。
const s1 = Symbol('foo') console.log(Symbol.keyFor(s1)) // undefinedconst s2 = Symbol.for('foo') console.log(Symbol.keyFor(s2)) // foo4. 作為屬性名
由于每一個 Symbol 值都是不相等的,這意味著 Symbol 值可以作為標識符,用于對象的屬性名,就能保證不會出現同名的屬性。這對于一個對象由多個模塊構成的情況非常有用,能防止某一個鍵被不小心改寫或覆蓋。
const grade = {zhangsan: {address: 'xxx',tel: '111'},lisi: {address: 'yyy',tel: '222'},lisi: {address: 'zzz',tel: '333'}, } console.log(grade) // 只會保留一個lisi,因為key不能相同使用Symbol 來保留兩個人的信息:
const stu1 = Symbol('lisi') const stu2 = Symbol('lisi') const grade = {[stu1]: {address: 'yyy',tel: '222'},[stu2]: {address: 'zzz',tel: '333'}, } console.log(grade) console.log(grade[stu1]) console.log(grade[stu2])5. 屬性遍歷
const sym = Symbol('imooc') class User {constructor(name) {this.name = namethis[sym] = 'imooc.com'}getName() {return this.name + this[sym]} } const user = new User('xiecheng') console.log(user.getName())在上面的對象中有兩個屬性,一個是name,一個是Symbol類型的,對象的遍歷在上一節已經講過,有for...in、Object.keys、Object.getOwnPropertySymbols、Reflect.ownKeys,前面兩種只能獲取name,第三種只能獲取Symbol,只有Reflect.ownKeys可以獲取兩種類型的值。
for (let key of Reflect.ownKeys(user)) {console.log(key) }6. 消除魔術字符串
魔術字符串指的是,在代碼之中多次出現、與代碼形成強耦合的某一個具體的字符串或者數值。風格良好的代碼,應該盡量消除魔術字符串,改由含義清晰的變量代替。
function getArea(shape) {let area = 0switch (shape) {case 'Triangle':area = 1breakcase 'Circle':area = 2break}return area } console.log(getArea('Triangle'))上面代碼中,字符串Triangle和Circle就是魔術字符串。它多次出現,與代碼形成“強耦合”,不利于將來的修改和維護。
使用Symbol就可以很好的解決這個問題:
const shapeType = {triangle: Symbol(),circle: Symbol() }function getArea(shape) {let area = 0switch (shape) {case shapeType.triangle:area = 1breakcase shapeType.circle:area = 2break}return area } console.log(getArea(shapeType.triangle))總結
以上是生活随笔為你收集整理的【ES6(2015)】Symbol的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【ES6(2015)】Reflect
- 下一篇: webdrive不更新_关于seleni