Symbol函数
Symbol函數
- 概述
- Symbol.prototype.description
- 作為屬性名
- 消除魔術字符串
- 屬性名的遍歷
- Symbol.for(),Symbol.keyFor()
- 實例:模塊的 Singleton 模式
- 內置的 Symbol 值
概述
ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是 JavaScript 語言的第七種數據類型,前六種是:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。
通過Symbol函數生成
Symbol函數前不能使用new命令,否則會報錯。這是因為生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由于 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似于字符串的數據類型。
Symbol函數的參數只是表示對當前 Symbol 值的描述,因此相同參數的Symbol函數的返回值是不相等的。
// 沒有參數的情況 let s1 = Symbol(); let s2 = Symbol();s1 === s2 // false// 有參數的情況 let s1 = Symbol('foo'); let s2 = Symbol('foo');s1 === s2 // false如果 Symbol 的參數是一個對象,就會調用該對象的toString方法,將其轉為字符串,然后才生成一個 Symbol 值。
Symbol 值不能與其他類型的值進行運算,會報錯。
Symbol 值可以顯式轉為字符串,調用.toString()
可以轉換為布爾值
Symbol.prototype.description
const sym = Symbol('foo');sym.description // "foo"作為屬性名
每一個 Symbol 值都是不相等的,這意味著 Symbol 值可以作為標識符,用于對象的屬性名
let mySymbol = Symbol();// 第一種寫法 let a = {}; a[mySymbol] = 'Hello!';// 第二種寫法 let a = {[mySymbol]: 'Hello!' };// 第三種寫法 let a = {}; Object.defineProperty(a, mySymbol, { value: 'Hello!' });// 以上寫法都得到同樣結果 a[mySymbol] // "Hello!"注意,Symbol 值作為對象屬性名時,不能用點運算符。
const mySymbol = Symbol(); const a = {};a.mySymbol = 'Hello!'; a[mySymbol] // undefined a['mySymbol'] // "Hello!"點運算符后面總是字符串,所以不會讀取mySymbol作為標識名所指代的那個值,導致a的屬性名實際上是一個字符串 ‘mySymbol’,而不是一個 Symbol 值
在對象的內部,使用 Symbol 值定義屬性時,Symbol 值必須放在方括號之中
消除魔術字符串
魔術字符串指的是,在代碼之中多次出現、與代碼形成強耦合的某一個具體的字符串或者數值。
屬性名的遍歷
Symbol 作為屬性名,遍歷對象的時候,該屬性不會出現在for…in、for…of循環中,也不會被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
Object.getOwnPropertySymbols()方法,可以獲取指定對象的所有 Symbol 屬性名。該方法返回一個數組,成員是當前對象的所有用作屬性名的 Symbol 值。
Reflect.ownKeys()方法可以返回所有類型的鍵名,包括常規鍵名和 Symbol 鍵名。
以利用這個特性,為對象定義一些非私有的、但又希望只用于內部的方法。
Symbol.for(),Symbol.keyFor()
Symbol.for()方法可以做到這一點。它接受一個字符串作為參數,然后搜索有沒有以該參數作為名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建一個以該字符串為名稱的 Symbol 值,并將其注冊到全局
let s1 = Symbol.for('foo'); let s2 = Symbol.for('foo');s1 === s2 // trueSymbol.for("bar") === Symbol.for("bar") // trueSymbol("bar") === Symbol("bar") // falseSymbol()寫法沒有登記機制,所以每次調用都會返回一個不同的值
Symbol.keyFor()方法返回一個已登記的 Symbol 類型值的key。
let s1 = Symbol.for("foo");//Symbol.for()為 Symbol 值登記的名字,是全局環境的 Symbol.keyFor(s1) // "foo"let s2 = Symbol("foo");//未登記的 Symbol 值 Symbol.keyFor(s2) // undefined*Symbol.for()的這個全局登記特性,可以用在不同的 iframe 或 service worker 中取到同一個值
*
實例:模塊的 Singleton 模式
Singleton 模式指的是調用一個類,任何時候返回的都是同一個實例。
內置的 Symbol 值
11 個內置的 Symbol
Symbol.hasInstance屬性,指向一個內部方法,其他對象使用instanceof運算符,判斷是否為該對象的實例時,會調用這個方法。比如,foo instanceof Foo在語言內部,實際調用的是FooSymbol.hasInstance。
.isConcatSpreadable屬性等于一個布爾值,表示該對象用于Array.prototype.concat()時,是否可以展開
數組的默認行為是可以展開,Symbol.isConcatSpreadable默認等于undefined。該屬性等于true時,也有展開的效果。
類似數組的對象正好相反,默認不展開。它的Symbol.isConcatSpreadable屬性設為true,才可以展開。
Symbol.species屬性,指向一個構造函數。創建衍生對象時,會使用該屬性
Symbol.match
Symbol.replace
Symbol.toStringTag屬性,指向一個方法。在該對象上面調用Object.prototype.toString方法時,如果這個屬性存在,它的返回值會出現在toString方法返回的字符串之中,表示對象的類型。也就是說,這個屬性可以用來定制[object Object]或[object Array]中object后面的那個字符串。
Symbol.unscopables屬性,指向一個對象。該對象指定了使用with關鍵字時,哪些屬性會被with環境排除。
總結
- 上一篇: 利用zui上传excel文件,并通过ja
- 下一篇: 万有引力索源