Symbol是原始值,所以調用new Symbol會致使程序拋出錯誤數組
let firstName = Symbol() let person = {} person[firstName] = "angela" console.log(person[firstName])
使用typeof來辨別其類型函數
let symbol=Symbol('this is test description') console.log(typeof symbol)//symbol
Symbol可用於計算對象字面量屬性名、Object.defineProperty、Object.definePropertiesui
若是想建立一個共享的Symbol,可以使用Symbol.for方法this
let uid = Symbol.for('uid') let object = { [uid]: '12345' } console.log(object[uid])//12345 console.log(uid)//Symbol(uid) let uid2 = Symbol.for('uid') console.log(uid === uid2)//true console.log(object[uid2])//12345 console.log(uid2)//Symbol(uid)
Symbol.keyFor方法在Symbol全局註冊表中檢索與Symbol有關的鍵spa
let uid = Symbol.for('uid') console.log(Symbol.keyFor(uid))//uid let uid2 = Symbol.for('uid') console.log(Symbol.keyFor(uid2))//uid let uid3=Symbol('uid') console.log(Symbol.keyFor(uid3))//undefined
Symbol全局註冊表是一個相似全局做用域的共享環境,也就是說你不能假設目前環境中存在哪些鍵prototype
不能將Symbol強制轉換成數字類型,Symbol也不能夠被轉換成字符串code
let uid = Symbol.for('uid') let desc = uid + ""//報錯 Uncaught TypeError: Cannot convert a Symbol value to a string
let uid = Symbol.for('uid') let desc = uid / 1//報錯 Uncaught TypeError: Cannot convert a Symbol value to a number
可是卻能夠像下面這樣使用對象
let uid = Symbol.for('uid') let desc = String(uid) console.log(desc)//Symbol(uid)
Object.getOwnPropertySymbolsblog
let uid = Symbol.for('uid') let object = { [uid]: '12345' } let symbols=Object.getOwnPropertySymbols(object)
Symbol.hasInstance只接受一個參數,即要檢查的值
每一個函數都有Symbol.hasInstance方法,用於肯定對象是否爲函數實例,該方法在Function.prototype中定義,該方法被定義不爲可寫、不可配置、不可枚舉圖片
let obj = [] //obj instanceof Array //下面一句代碼與此句功能等價 Array[Symbol.hasInstance](obj)//true
咱們能夠經過Object.defineProperty方法改寫一個不可寫屬性
因此其實能夠重寫全部內建函數(如Date和Error)默認的Symbol.hasInstance屬性
function SpecialNumber() { } Object.defineProperty(SpecialNumber, Symbol.hasInstance, { value: function (v) { return (v instanceof Number) && (v >= 1 && v <= 100) } }) var two = new Number(2), zero = new Number(0); console.log(two instanceof SpecialNumber)//true console.log(zero instanceof SpecialNumber)//false
Symbol.isConcatSpreadable屬性值爲true代表屬性值應看成爲獨立元素添加到數組中
let c1 = ['red', 'green'], c2 = c1.concat(['blue', 'black'], 'yellow') console.log(c2)//["red", "green", "blue", "black", "yellow"]
爲何上面一段代碼結果是["red", "green", "blue", "black", "yellow"]而不是["red", "green", ["blue", "black"], "yellow"]?
若是把上面的代碼稍微改一下,結果就徹底不同了
let collection = { 0: 'hello', 1: 'world', 2: 'demo', 3: 'test', [Symbol.isConcatSpreadable]: true, length: 4 } let msg = ['Hi'].concat(collection) console.log(msg)//["Hi", "hello", "world", "demo", "test"]
let hasLenOf10 = { [Symbol.match](v) { return v.length === 10 ? [v.substring(0, 10)] : null }, [Symbol.replace](v, replacement) { return v.length === 10 ? replacement + v.substring(10) : v; }, [Symbol.search](v) { return v.length === 10 ? 0 : -1 }, [Symbol.split](v) { return v.length === 10 ? ["", ""] : [v] } } let msg1 = 'Hello world', msg2 = 'Hello John'; console.log(msg1.match(hasLenOf10))//null console.log(msg2.match(hasLenOf10))//[Hello John] console.log(msg1.replace(hasLenOf10))//Hello world console.log(msg2.replace(hasLenOf10))//undefined console.log(msg1.search(hasLenOf10))//-1 console.log(msg2.search(hasLenOf10))//0 console.log(msg1.split(hasLenOf10))//["Hello world"] console.log(msg2.split(hasLenOf10))//["",""]
在執行特定操做時,常常會嘗試將對象轉換到相應的原始值
Symbol.toPrimitive被定義在每個標準類型的原型上,而且規定了當對象被轉換爲原始值時應該執行的操做
每當執行類型轉換總會調用Symbol.toPrimitive方法並傳入一個值做爲參數,這個值在規範中被稱做類型提示hint,類型提示參數只有三種選擇number、string、default
function Temperature(degree) { this.degree = degree } Temperature.prototype[Symbol.toPrimitive] = function (hint) { switch (hint) { case "string": return this.degree + '\u00b0'; case "number": return this.degree; case "default": return this.degree + " degrees" } } var freezing = new Temperature(32) console.log(freezing + "!")//32 degrees! console.log(freezing / 2)//16 console.log(String(freezing))//32°
之前判斷一個對象的類型通常都是這樣
function isArray(value) { return Object.prototype.toString.call(value) === "[object Array]" }
ES6中咱們能夠自定義對象字符串標籤
function Person(name) { this.name = name } Person.prototype[Symbol.toStringTag] = "Person" Person.prototype.toString = function () { return this.name } var me = new Person('angela') console.log(me.toString())//angela console.log(Object.prototype.toString.call(me))//[object Person]
若是咱們不重寫toString方法,則me.toString返回的值就是[object Person]咱們能夠給Person.prototype[Symbol.toStringTag]賦任意值,固然也能夠修改原生對象的字符串標籤