- 預(yù)熱
javascript有 6種 數(shù)據(jù)類(lèi)型
- undefined
- null
- 布爾值(Boolean)
- 字符串(String)
- 數(shù)值(Number)
- 對(duì)象(Object)
而 symbol 為ES6新增的數(shù)據(jù)類(lèi)型。表示獨(dú)一無(wú)二的值,使用Symbol()定義(S大寫(xiě)!)
- 理解symbol
那么這個(gè)symbol到底是個(gè)什么東西,我們看下面例子:
const a = Symbol()
const b = Symbol()
console.log(a==b) // false
在我理解,就是對(duì)a、b進(jìn)行隨機(jī)賦值,并且永遠(yuǎn)不會(huì)重復(fù)
再來(lái)一個(gè)例子
const b = Symbol();
let a = {};
a[b] = 'red';
console.log(a[b]); // red
console.log(a) // {Symbol(): "red"}
a = {
[b]: 'blue',
b: 'black'
}
console.log(a); // {b: "black", Symbol(): "blue"}
a.b = 'yellow'
console.log(a); //{b: "yellow", Symbol(): "blue"}
a[b] = 'black'
console.log(a); //{b: "yellow", Symbol(): "black"}
a['b'] = 'white'
console.log(a); // {b: "white", Symbol(): "black"}
我們可以看到,如果用Symbol()生成的symbol在對(duì)象中顯示的是Symbol()而不對(duì)定義的b,
而需要對(duì)symbol值進(jìn)行修改則需要使用a[b];通過(guò)這里我們可以看到symbol的一個(gè)使用好處就是不會(huì)被不經(jīng)意的a.b修改了值
- symbol使用
- 寫(xiě)法
let mySymbol = Symbol();
// 第一種寫(xiě)法
let a = {};
a[mySymbol] = 'Hello!';
// 第二種寫(xiě)法
let a = {
[mySymbol]: 'Hello!'
};
// 第三種寫(xiě)法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上寫(xiě)法都得到同樣結(jié)果
a[mySymbol] // "Hello!"
- 添加描述
const sym = Symbol('name');
console.log(sym); // Symbol(name)
定義在Symbol()內(nèi)添加描述
ES2019 提供方法descripttion
const sym = Symbol('name');
console.log(sym.description); // name
- 賦值
let mySymbol = Symbol();
// 第一種寫(xiě)法
let a = {};
a[mySymbol] = 'Hello!';
// 第二種寫(xiě)法
let a = {
[mySymbol]: 'Hello!'
};
// 第三種寫(xiě)法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上寫(xiě)法都得到同樣結(jié)果
a[mySymbol] // "Hello!"
- 遍歷
Symbol 作為屬性名,該屬性不會(huì)出現(xiàn)在for...in、for...of循環(huán)中,也不會(huì)被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有屬性,有一個(gè)Object.getOwnPropertySymbols方法,可以獲取指定對(duì)象的所有 Symbol 屬性名
《ECMAscript 6入門(mén)》 ——阮一峰
如果要遍歷symbol則需要使用 Object.getOwnPropertySymbols 方法
const a = Symbol('a')
const b = Symbol('b')
const symList = {
[a]: 1,
[b]: 2
}
console.log(Object.getOwnPropertySymbols(symList)); // [Symbol(a), Symbol(b)]
Object.getOwnPropertyNames方法得不到Symbol屬性名;
不過(guò),另一個(gè)新的 API,Reflect.ownKeys方法可以返回所有類(lèi)型的鍵名,包括常規(guī)鍵名和 Symbol 鍵名。
- Symbol.for(),Symbol.keyFor()
一開(kāi)始我們說(shuō)過(guò)symbol的概念,symbol為唯一的;但是我們非要使用相同的symbol值呢;
這時(shí)候我們就得用 Symbol.for() 了
const a = Symbol.for('c')
const b = Symbol.for('c')
console.log(a == b); // true
console.log(a); // Symbol(c)
獲取Symbol.for()定義的描述可以通過(guò) Symbol.keyFor() 來(lái)獲取,但是如果是通過(guò)Symbol()寫(xiě)的描述就獲取不到了
const a = Symbol.for("c");
console.log(Symbol.keyFor(a)); // c
const b = Symbol("c");
console.log(Symbol.keyFor(b)); // undefined
- 代碼中使用/使用場(chǎng)景
比如我們要進(jìn)行判斷,而判值提前定義為常量
const a = 'NAME_A'
const b = 'NAME_B'
const c = 'NAME_C'
function Func(val) {
switch (val) {
case a:
return 1
case b:
return 2
case c:
return 3
default:
return -1
}
}
console.log(Func(a)); // 1
這里我們并不關(guān)心obj里對(duì)象值是什么此時(shí)我們使用Symbol()
const a = Symbol('a')
const b = Symbol('b')
const c = Symbol('c')
function Func(val) {
switch (val) {
case a:
return 1
case b:
return 2
case c:
return 3
default:
return -1
}
}
console.log(Func(a)); // 1