一種新的資料型別Symbol
阿新 • • 發佈:2020-07-14
symbol 是一種基本資料型別 (primitive data type)。Symbol()函式會返回symbol型別的值,該型別具有靜態屬性和靜態方法。它的靜態屬性會暴露幾個內建的成員物件;它的靜態方法會暴露全域性的symbol註冊,且類似於內建物件類,但作為建構函式來說它並不完整,因為它不支援語法:"new Symbol()"。每個從Symbol()返回的symbol值都是唯一的。一個symbol值能作為物件屬性的識別符號;這是該資料型別僅有的目的。
他是一個新的基本資料型別並且為唯一值
let s1 = Symbol() let s2 = Symbol() console.log(s1); console.log(s1===s2); // false
symbol 會自動呼叫原型中的toString方法
const obj = {
name: 'es6',
toString () {
return this.name
}
}
let s = Symbol(obj)
console.log(s) // 輸出es6
API
Symbol.for() 會去尋找是否宣告過,如果已宣告將會指向同一個,否則註冊一個Symbol
let s1 = Symbol('foo')
let s2 = Symbol('foo')
console.log(s1===s2) // false
Symbol.keyFor() 返回一個已經註冊的 Symbol
const s1 = Symbol('foo')
console.log(Symbol.keyFor(s1)); // undefined
const s2 = Symbol.for('foo')
console.log(Symbol.keyFor(s2)); // foo
應用場景
- 當物件中需存入兩個鍵名相同的鍵值對時(例如姓名相同的人),可使用Symbol來區分.
const stu1 = Symbol('李四') const stu2 = Symbol('李四') const grade = { [stu1]: { address: 'xxx', tel:'1111' }, [stu2]: { address: 'xxx', tel:'22222' } } console.log(grade); // 並沒有被覆蓋掉 console.log(grade[stu2]); // {address: 'xxx',tel:'22222'}
- 可以對物件進行封裝, 類似於隱藏屬性, 通過for in遍歷不出, 通過let key of Reflect.ownKeys(obj) 可以遍歷出
const sym = Symbol('es5')
class User {
constructor(name) {
this.name = name
this[sym] = 'es6'
}
getName () {
return this.name + ' ' + this[sym]
}
}
const user = new User('es5')
console.log(user.getName()); // es5 es6
for (let key in user) {
console.log(key);
} // name
for (let key of Object.getOwnPropertySymbols(user)) {
console.log(key);
} // name Symbol(es5)
- 消除魔術字串
魔術字串指的是,在程式碼之中多次出現、與程式碼形成強耦合的某一個具體的字串或者數值。風格良好的程式碼,應該儘量消除魔術字串,改由含義清晰的變數代替。
function getArea (shape) {
let area = 0
switch (shape) {
case 'Triangle':
area = 1
break
case 'Circle':
area = 2
break
}
return area
}
console.log(getArea('Triangle')); //1
使用Symbol()的唯一性代替原來'Triangle',程式碼看起來更加清晰,減少出錯率
const shapeType = {
triangle: Symbol(),
circle: Symbol()
}
function getArea (shape) {
let area = 0
switch (shape) {
case shapeType.triangle:
area = 1
break
case shapeType.circle:
area = 2
break
}
return area
}
console.log(getArea(shapeType.circle)); // 2