1、數(shù)據(jù)類型Symbol
特點(diǎn):在使用別人提供的對(duì)象時(shí),在拿到這個(gè)對(duì)象,然后想往里面添加新的屬性名,為了防止和別人的屬性名重復(fù),這樣是會(huì)發(fā)生沖突的,對(duì)象的屬性名必須要求是獨(dú)一無二的,因此,ES6中加入了Symbol數(shù)據(jù)類型,確保對(duì)象的屬性名獨(dú)一無二。
Symbol實(shí)際上是引入的一種原始數(shù)據(jù)類型
// ES6的symbol
let sym = Symbol("addr");
console.log(sym);
console.log(typeof sym);

1.1、Symbol函數(shù)前不能用new
Symbol函數(shù)不是一個(gè)構(gòu)造函數(shù),前面不能用new操作符,所以Symbol類型的值也不是對(duì)象,不能添加任何屬性,只是類似于字符型的數(shù)據(jù)類型,強(qiáng)加new操作符會(huì)報(bào)錯(cuò)!
1.2、Symbol的用處
一般作為json的key屬性使用
let symName = Symbol('name');
let symAge = Symbol('age');
let json = {
[symName]:'小陳',
[symAge]:'23'
}
console.log(json);
console.log(json[symName]);
console.log(json[symAge]);

1.3、Symbol函數(shù)的參數(shù)
Symbol函數(shù)還可以接受一個(gè)字符參數(shù),來對(duì)產(chǎn)生的Symbol值進(jìn)行描述,方便我們區(qū)分不同的Symbol值
let symName = Symbol('test');
let symAddr = Symbol('test');
console.log('symName',symName);
console.log('symAddr',symAddr);
console.log('symName == symAddr?',symName == symAddr);
let sAddr = Symbol('symAddr');
console.log('sAddr == symAddr?',sAddr == symAddr);

1.4、對(duì)象作為參數(shù)
如果Symbol函數(shù)的參數(shù)是一個(gè)對(duì)象,就會(huì)調(diào)用該對(duì)象的toString方法,將其轉(zhuǎn)化為一個(gè)字符串,然后生成一個(gè)Symbol值,所以,Symbol函數(shù)的參數(shù)只能是字符串。
let sym = Symbol({ name:'小陳' });
console.log(sym);
console.log('類型',typeof(sym));

1.5、Symbol值不可以進(jìn)行運(yùn)算
Symbol是一種數(shù)據(jù)類型,但它與Number以及String類型不同,不能參與運(yùn)算,Symbol值可以轉(zhuǎn)化為字符串或布爾值,但是不能轉(zhuǎn)為數(shù)值。
let sym1 = Symbol('sym1');
let sym2 = Symbol('sym2');
//轉(zhuǎn)為字符串
console.log(String(sym1));
//轉(zhuǎn)為布爾值
console.log(Boolean(sym2));
// 直接進(jìn)行運(yùn)算
console.log('sym1+sym2=?',sym1+sym2);

1.6、Symbol作為屬性
Symbol就是用于屬性去創(chuàng)造的,下面是幾種Symbol作為屬性的寫法
//寫法一:
let obj = {}; //創(chuàng)建一個(gè)對(duì)象
let sym = Symbol();
obj[sym] = '湖南省長沙市';
//取屬性值
console.log(obj[sym]);

// 寫法二
let sym = Symbol();
let obj = {
[sym]:'安徽省蕪湖市'
};
console.log(obj[sym]);

//寫法三
let obj = {}
let sym = Symbol()
Object.defineProperty(obj,sym,{value:'小陳同學(xué)'});
console.log(obj[sym]);

Symbol值作為屬性名時(shí),獲取相應(yīng)的屬性值不能用作點(diǎn)運(yùn)算符,如果點(diǎn)運(yùn)算符來給對(duì)象的屬性賦Symbol類型的值,實(shí)際上屬性名會(huì)變成字符串,而不是Symbol值,在對(duì)象內(nèi)部,使用Symbol值定義屬性時(shí),Symbol值必須放在方括號(hào)內(nèi),否則就是一個(gè)字符串。
1.7、Symbol值作為屬性名的遍歷
Symbol值的屬性,無法通過for循環(huán)(for...of...或是for....in...),Symbol值作為對(duì)象的屬性名,也無法通過Object.keys()、Object.getOwnPropertyNames()來獲取,但是提供了一個(gè)Object.getOwnPropertySymbols()方法獲取對(duì)象上的Symbol屬性名。
let sym1 = Symbol('sym1');
let sym2 = Symbol('sym2');
let obj = {
name:'小陳同學(xué)',
age:22,
[sym1]:'湖南省長沙市',
[sym2]:'安徽省蕪湖市',
}
console.log(Object.getOwnPropertySymbols(obj));

如果我們用遍歷屬性的方法 for...of...去做會(huì)報(bào)什么錯(cuò)誤呢?
let sym1 = Symbol('sym1');
let sym2 = Symbol('sym2');
let obj = {
name:'小陳同學(xué)',
age:22,
[sym1]:'湖南省長沙市',
[sym2]:'安徽省蕪湖市',
}
for(var i of obj){
console.log(i)
}

報(bào)錯(cuò)提示的很明顯,需要Symbol類型的迭代器去操作。