* 學習Symbol
* 首先Symbol是什麼?它是新的(第七種)原始數據類型 null undefined Object Boolean String Number
* 其次Symbol可以用來做什麼? 可以作爲對象的屬性名,可以保證不會與其他屬性名產生衝突
* 特點:
* 1. 不能使用new命令 值不是對象 類似於字符串的一種數據類型
* 2. Symbol值是通過Symbol函數生成的 Symbol函數可以接受一個字符串作爲參數
* 3. Symbol值不能和其他字符串拼接 也不能轉換成數值 可以顯式的轉換成Boolean值
* 4. Symbol值就算參數相同 值也不一樣,所以可以作爲標識符,用於對象的屬性名,爲了保證不同名 不被覆蓋
// 第一: 簡單的列舉
let a = Number()
let b = String()
let c = Boolean()
let d = Symbol()
console.log(typeof a, typeof b, typeof c, typeof d) // number string boolean symbol
// 第二: 沒有參數 || 相同參數的情況下
let a = Symbol()
let b = Symbol()
console.log(a===b) // false
let c = Symbol('hello')
let d = Symbol('hello')
console.log(c === d) // false
// 結論: 獨一無二, 無參數不好區分
// 第三: 例子 有參數 參數是字符串的情況下
let a = Symbol('hello')
let b = Symbol('nihao')
console.log(a, b) // Symbol(hello) Symbol(nihao)
// 第四: 例子 有參數 參數是對象的情況下
let obj = {
name: '婷'
}
let myname = Symbol(obj)
console.log(myname) // Symbol([object Object])
// 第五: 有參數 參數是對象時 需要調用toString()一下
let obj = {
toString() {
return '婷'
}
}
let myname = Symbol(obj)
console.log(myname) // Symbol(婷)
// 第六 Symobol值和其他值
let myname = Symbol('婷')
console.log('my name is'+ myname) // 報錯: Cannot convert symbol value to string 無法將符號值轉換爲字符串
let num = Symbol() // Symbol('nihao') Symbol('1') Symbol(false) 六個數據類型放裏面
Boolean(num)
if(num){
console.log('正確') // 永遠是正確
}
//結論: 和其他值不能像其他字符串那樣拼接使用 但是可以顯式的轉換成Boolean值 但是永遠是true
// 第七: Symbol 描述 description
const sym = Symbol('婷')
let str = String(sym)
let newstr = str.toString()
console.log(str, newstr) // Symbol(婷) Symbol(婷)
let newstr = sym.description
console.log(newstr) // 婷
// 第八 作爲屬性名的 賦值的方法 Symbol 不能用. 用.之後後面就是字符串 而不是一個變量
let myage = Symbol()
// 第一種:
let a = {}
a.myage = '123' // {myage: 123} 錯誤
a[myage] = '12' // {Symbol(): "12"} 正確
// 第二種:
let a = {
[myage]: '26'
}
console.log(a) // {Symbol(): "26"} 正確
// 第三種:
let a = {};
Object.defineProperty(a, myage,{value: '18'})
console.log(a) // {Symbol(): "18"} 正確
// 第九 對象內部使用Symbol值定義屬性時 將Symbol值放在[], [Symbol值]這樣還是代表的這個值,如果不放[]的話。和.沒什麼兩樣,就成了普通的字符串
let sym = Symbol('nihao');
// 第一種:
let obj = {
[sym]: (arg)=>{
return arg +'哈哈'
}
}
// 第二種: 稍微簡寫一點
let obj = {
[sym](arg){
return arg +'哈哈'
}
}
console.log(obj[sym](123)) // 123哈哈 obj={Symbol(nihao):f}
// 第十: 定義常量
const log= {}
log.levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn')
}
console.log(log.levels.DEBUG,log.levels.INFO,log.levels.WARN)
// 結論: 意義暫時不清楚
// 第十一: 當Symbol作爲對象的屬性名, 遍歷對象時,這個屬性不會出現在常用的循環方法中,有一個方法:Object.getOwnPropertySymbols() 可以獲取Symbol作爲的鍵名
const obj = {}
let a = Symbol('a')
let b = Symbol('b')
obj[a] = '我是a'
obj[b] = '我是b'
console.log(obj) // {Symbol(a): "我是a", Symbol(b): "我是b"}
// 想要獲取obj中所有的屬性
//1: for...in
for(let key in obj){
console.log(key, 'key')// 什麼也沒有
}
//2: for...of
for(let key of obj){
console.log(key, obj[key]) //報錯: obj is not iterable
}
//3. getOwnPropertyNames
console.log(Object.getOwnPropertyNames(obj)) // []
//4.getOwnPropertySymbols
console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(a), Symbol(b)]
// 第十二: Reflect.ownKeys() 獲取所有的鍵名 常規的包括Symbol值作爲的鍵名
let obj = {
[Symbol('name')]: '婷',
age: 26,
like: 'smile',
}
console.log(Reflect.ownKeys(obj)) // ["age", "like", Symbol(name)] 順序會有點不一樣 數組前面是常規的鍵名最後是Symbol鍵名
未完待續…