Js中Symbol對象
ES6
引入了一種新的基本數據類型Symbol
,表示獨一無二的值,最大的用法是用來定義對象的唯一屬性名,Symbol()
函數會返回symbol
類型的值,該類型具有靜態屬性和靜態方法,其靜態屬性會暴露幾個內建的成員對象,它的靜態方法會暴露全局的symbol
注冊,且類似於內建對象類,但作為構造函數來說它並不完整,因為它不支持語法new Symbol()
。每個從Symbol()
返回的symbol
值都是唯一的,一個symbol
值能作為對象屬性的標識符。
描述
對於每一個Symbol
的值都是不相等的,所以Symbol
作為對象的屬性名,可以保證屬性不重名。該數據類型通常被用作一個對象屬性的鍵值,例如當想使對象屬性的鍵為私有值時。symbol
類型的鍵存在於各種內置的JavaScript
對象中,同樣自定義類也可以這樣創建私有成員。symbol
數據類型具有非常明確的目的,並且因為其功能性單一的優點而突出,一個symbol
實例可以被賦值到一個左值變量,還可以通過標識符檢查類型,這就是其全部特性。一個具有數據類型symbol
的值可以被稱為符號類型值,在JavaScript
運行時環境中,一個符號類型值可以通過調用函數Symbol()
創建,這個函數動態地生成了一個匿名,唯一的值。Symbol
類型唯一合理的用法是用變量存儲symbol
的值,然后使用存儲的值創建對象屬性。
let s = Symbol();
let s1 = Symbol("s");
let s2 = Symbol("s");
console.log(s === s1); //false
console.log(s1 === s2); //false
let obj = {};
let prop = Symbol();
obj[prop] = 1;
console.log(obj[prop]); // 1
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol()]
console.log(Reflect.ownKeys(obj)); // [Symbol()]
屬性
Symbol.length
: 長度屬性,值為0
。Symbol.prototype
:symbol
構造函數的原型。Symbol.iterator
: 返回一個對象默認迭代器的方法,被for...of
使用。Symbol.match
: 用於對字符串進行匹配的方法,也用於確定一個對象是否可以作為正則表達式使用,被String.prototype.match()
使用。Symbol.replace
: 替換匹配字符串的子串的方法,被String.prototype.replace()
使用。Symbol.search
: 返回一個字符串中與正則表達式相匹配的索引的方法,被String.prototype.search()
使用。Symbol.split
: 在匹配正則表達式的索引處拆分一個字符串的方法,被String.prototype.split()
使用。Symbol.hasInstance
: 確定一個構造器對象識別的對象是否為它的實例的方法,被instanceof
使用。Symbol.isConcatSpreadable
: 布爾值,表明一個對象是否應該flattened
為它的數組元素,被Array.prototype.concat()
使用。Symbol.unscopables
: 擁有和繼承屬性名的一個對象的值被排除在與環境綁定的相關對象外。Symbol.species
: 一個用於創建派生對象的構造器函數。Symbol.toPrimitive
: 一個將對象轉化為基本數據類型的方法。Symbol.toStringTag
: 用於對象的默認描述的字符串值,被Object.prototype.toString()
使用。
方法
Symbol.for()
Symbol.for(key)
Symbol.for(key)
方法會根據給定的鍵key
,來從運行時的symbol
注冊表中找到對應的symbol
,如果找到了就返回它,否則就新建一個與該鍵關聯的symbol
,並放入全局symbol
注冊表中。和Symbol()
不同的是,用Symbol.for()
方法創建的的symbol
會被放入一個全局symbol
注冊表中。當然Symbol.for()
並不是每次都會創建一個新的symbol
,它會首先檢查給定的key
是否已經在注冊表中了。假如是則會直接返回上次存儲的那個,否則它會再新建一個。
key
: 一個字符串,作為symbol
注冊表中與某symbol
關聯的鍵,同時也會作為該symbol
的描述。
var s1 = Symbol.for();
var s2 = Symbol.for("s");
var s3 = Symbol.for();
var s4 = Symbol.for("s");
console.log(s1 === s3); // true
console.log(s2 === s4); // true
Symbol.keyFor()
Symbol.keyFor(sym)
Symbol.keyFor(sym)
方法用來獲取全局symbol
注冊表中與某個symbol
關聯的鍵,如果全局注冊表中查找到該symbol
,則返回該symbol
的key
值,返回值為字符串類型,否則返回undefined
。
sym
: 必選參數,需要查找鍵值的某個Symbol
。
var s1 = Symbol();
var s2 = Symbol.for("s");
var key1 = Symbol.keyFor(s1);
var key2 = Symbol.keyFor(s2);
console.log(key1); // undefined
console.log(key2); // s
Symbol.prototype.toString()
symbol.toString()
toString()
方法返回當前symbol
對象的字符串表示,Symbol
對象擁有自己的toString
方法,因而遮蔽了原型鏈上的Object.prototype.toString()
,symbol
原始值不能轉換為字符串,所以只能先轉換成它的包裝對象,再調用toString()
方法。
var s = Symbol.for("s");
console.log(s.toString()); // Symbol(s)
console.log(Object(Symbol("s")).toString()); // Symbol(s)
Symbol.prototype.valueOf()
symbol.valueOf()
valueOf()
方法返回當前symbol
對象所包含的symbol
原始值。在JavaScript
中,雖然大多數類型的對象在某些操作下都會自動的隱式調用自身的valueOf()
方法或者toString()
方法來將自己轉換成一個原始值,但symbol
對象不會這么干,symbol
對象無法隱式轉換成對應的原始值。
var s = Symbol.for("s");
console.log(s.valueOf()); // Symbol(s)
Symbol.prototype[@@toPrimitive]
Symbol()[Symbol.toPrimitive](hint)
[@@toPrimitive]()
方法可將Symbol
對象轉換為原始值,hint
參數未被使用。
var s = Symbol.for("s");
console.log(s[Symbol.toPrimitive]()); // Symbol(s)
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://www.runoob.com/w3cnote/es6-symbol.html
https://developer.mozilla.org/zh-CN/docs/Glossary/Symbol
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol