ES6學(xué)習(xí)筆記之Symbol

前端技術(shù)日新月異散罕,不斷有新技術(shù)出現(xiàn),我們就需要不斷地學(xué)習(xí)新知識(shí),雖然ES6已經(jīng)提出很久了碧浊,但是最近我才有時(shí)間靜下心來好好學(xué)習(xí)一下里面提出的新規(guī)則。今天總結(jié)下ES6提出的這個(gè)新的原始數(shù)據(jù)類型--Symbol瘟仿。

為啥需要Symbol

一個(gè)新規(guī)則的提出箱锐,必然是因?yàn)橛行枨螅煜S5的人都知道劳较,ES5里面對(duì)象的屬性名都是字符串驹止,如果你需要使用一個(gè)別人提供的對(duì)象,你對(duì)這個(gè)對(duì)象有哪些屬性也不是很清楚观蜗,但又想為這個(gè)對(duì)象新增一些屬性臊恋,那么你新增的屬性名就很可能和原來的屬性名發(fā)送沖突,顯然我們是不希望這種情況發(fā)生的墓捻。所以捞镰,我們需要確保每個(gè)屬性名都是獨(dú)一無二的,這樣就可以防止屬性名的沖突了。因此岸售,ES6里就引入了Symbol践樱,用它來產(chǎn)生一個(gè)獨(dú)一無二的值。

Sumbol是什么

我們已經(jīng)知道ES6中引入了一個(gè)叫Symbol的東西凸丸,但是這個(gè)東西到底是什么呢拷邢?是一個(gè)函數(shù)還是一個(gè)對(duì)象或者是其他什么?Symbol實(shí)際上是ES6引入的一種原始數(shù)據(jù)類型屎慢,除了Symbol瞭稼,JavaScript還有其他5種數(shù)據(jù)類型,分別是Undefined腻惠、Null环肘、Boolean、String集灌、Number悔雹、對(duì)象,這5種數(shù)據(jù)類型都是ES5中就有的欣喧。

怎么生成一個(gè)Symbol類型的值

既然我們已經(jīng)知道了Symbol是一種原始的數(shù)據(jù)類型腌零,那么怎么生成這種數(shù)據(jù)類型的值呢?Symbol值是通過Symbol函數(shù)生成的唆阿,如下:

let s = Symbol();
console.log(s);  // Symbol()
typeof s;  // "symbol"

上面代碼中益涧,s就是一個(gè)Symbol類型的值,它是獨(dú)一無二的驯鳖。

Symbol函數(shù)前不能用new

Symbol函數(shù)不是一個(gè)構(gòu)造函數(shù)闲询,前面不能用new操作符。所以Symbol類型的值也不是一個(gè)對(duì)象浅辙,不能添加任何屬性扭弧,它只是一個(gè)類似于字符型的數(shù)據(jù)類型。如果強(qiáng)行在Symbol函數(shù)前加上new操作符摔握,會(huì)報(bào)錯(cuò)寄狼,如下:

let s = new Symbol();
// Uncaught TypeError: Symbol is not a constructor(…)

Symbol函數(shù)的參數(shù)

字符串作為參數(shù)

用上面的方法生成的Symbol值不好進(jìn)行區(qū)分丁寄,Symbol函數(shù)還可以接受一個(gè)字符串參數(shù)氨淌,來對(duì)產(chǎn)生的Symbol值進(jìn)行描述,方便我們區(qū)分不同的Symbol值伊磺。

let s1 = Symbol('s1');
let s2 = Symbol('s2');
console.log(s1);  // Symbol(s1)
console.log(s2);  // Symbol(s2)
s1 === s2;  //  false
let s3 = Symbol('s2');
s2 === s3;  //  false

從上面代碼可以看出:

  1. 給Symbol函數(shù)加了參數(shù)之后盛正,控制臺(tái)輸出的時(shí)候可以區(qū)分到底是哪一個(gè)值;
  2. Symbol函數(shù)的參數(shù)只是對(duì)當(dāng)前Symbol值的描述屑埋,因此相同參數(shù)的Symbol函數(shù)返回值是不相等的豪筝;

對(duì)象作為參數(shù)

如果Symbol函數(shù)的參數(shù)是一個(gè)對(duì)象,就會(huì)調(diào)用該對(duì)象的toString方法,將其轉(zhuǎn)化為一個(gè)字符串续崖,然后才生成一個(gè)Symbol值敲街。所以,說到底严望,Symbol函數(shù)的參數(shù)只能是字符串多艇。

Symbol值可以進(jìn)行運(yùn)算么?

既然Symbol是一種數(shù)據(jù)類型像吻,那我們一定想知道Symbol值是否能進(jìn)行運(yùn)算峻黍。告訴你,Symbol值是不能進(jìn)行運(yùn)算的,不僅不能和Symbol值進(jìn)行運(yùn)算拨匆,也不能和其他類型的值進(jìn)行運(yùn)算姆涩,否則會(huì)報(bào)錯(cuò)。
Symbol值可以顯式轉(zhuǎn)化為字符串和布爾值惭每,但是不能轉(zhuǎn)為數(shù)值骨饿。

var mysym1 = Symbol('my symbol');
mysym1.toString() //  'Symbol('my symbol')'
String(mysym1)  //  'Symbol('my symbol')'
var mysym2 = Symbol();
Boolean(mysym2);  // true
Number(mysym2)  // TypeError: Cannot convert a Symbol value to a number(…)

Symbol如何作為屬性名

Symbol就是為對(duì)象的屬性名而生,那么Symbol值怎么作為對(duì)象的屬性名呢洪鸭?有下面幾種寫法:

let a = {};
let s4 = Symbol();
// 第一種寫法
a[s4] = 'mySymbol';
// 第二種寫法
a = {
    [s4]: 'mySymbol'
}
// 第三種寫法
Object.defineProperty(a, s4, {value: 'mySymbol'});
a.s4;  //  undefined
a.s4 = 'mySymbol';
a[s4]  //  undefined
a['s4']  // 'mySymbol'

從上面代碼可以看出:

  1. 使用對(duì)象的Symbol值作為屬性名時(shí)样刷,獲取相應(yīng)的屬性值不能用點(diǎn)運(yùn)算符;
  2. 如果用點(diǎn)運(yùn)算符來給對(duì)象的屬性賦Symbol類型的值览爵,實(shí)際上屬性名會(huì)變成一個(gè)字符串置鼻,而不是一個(gè)Symbol值;
  3. 在對(duì)象內(nèi)部蜓竹,使用Symbol值定義屬性時(shí)箕母,Symbol值必須放在方括號(hào)之中,否則只是一個(gè)字符串俱济。

Symbol值作為屬性名的遍歷

使用for...in和for...of都無法遍歷到Symbol值的屬性嘶是,Symbol值作為對(duì)象的屬性名,也無法通過Object.keys()蛛碌、Object.getOwnPropertyNames()來獲取了聂喇。但是,不同擔(dān)心蔚携,這種平常的需求肯定是會(huì)有解決辦法的希太。我們可以使用Object.getOwnPropertySymbols()方法獲取一個(gè)對(duì)象上的Symbol屬性名。也可以使用Reflect.ownKeys()返回所有類型的屬性名酝蜒,包括常規(guī)屬性名和 Symbol屬性名誊辉。

let s5 = Symbol('s5');
let s6 = Symbol('s6');
let a = {
    [s5]: 's5',
    [s6]: 's6'
}
Object.getOwnPropertySymbols(a);   // [Symbol(s5), Symbol(s6)]
a.hello = 'hello';
Reflect.ownKeys(a);  //  ["hello", Symbol(s5), Symbol(s6)]

利用Symbol值作為對(duì)象屬性的名稱時(shí),不會(huì)被常規(guī)方法遍歷到這一特性亡脑,可以為對(duì)象定義一些非私有的但是又希望只有內(nèi)部可用的方法堕澄。

Symbol.for()和Symbol.keyFor()

Symbol.for()函數(shù)也可以用來生成Symbol值邀跃,但該函數(shù)有一個(gè)特殊的用處,就是可以重復(fù)使用一個(gè)Symbol值蛙紫。

let s7 = Symbol.for('s7');
console.log(s7); // Symbol(s7)
s7.toString(); // "Symbol(s7)"
let s8 = Symbol.for('s8');
s7 === s8 //  true
let s9 = Symbol();
Symbol.keyFor(s9); // undefined
Symbol.keyFor(s8); // "s8"

Symbol.for()函數(shù)要接受一個(gè)字符串作為參數(shù)拍屑,先搜索有沒有以該參數(shù)作為名稱的Symbol值,如果有坑傅,就直接返回這個(gè)Symbol值丽涩,否則就新建并返回一個(gè)以該字符串為名稱的Symbol值。上面代碼中裁蚁,s7和s8實(shí)際上就是同一個(gè)Symbol值矢渊,所以兩者是相等的。
Symbol.keyFor()函數(shù)是用來查找一個(gè)Symbol值的登記信息的枉证,Symbol()寫法沒有登記機(jī)制矮男,所以返回undefined;而Symbol.for()函數(shù)會(huì)將生成的Symbol值登記在全局環(huán)境中室谚,所以Symbol.keyFor()函數(shù)可以查找到用Symbol.for()函數(shù)生成的Symbol值毡鉴。

內(nèi)置Symbol值

ES6提供了11個(gè)內(nèi)置的Symbol值,分別是Symbol.hasInstance 秒赤、Symbol.isConcatSpreadable 猪瞬、Symbol.species 、Symbol.match 入篮、Symbol.replace 陈瘦、Symbol.search 、Symbol.split 潮售、Symbol.iterator 痊项、Symbol.toPrimitive 、Symbol.toStringTag 酥诽、Symbol.unscopables 等鞍泉。
有興趣的可以自行了解:http://es6.ruanyifeng.com/#docs/symbol

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肮帐,隨后出現(xiàn)的幾起案子咖驮,更是在濱河造成了極大的恐慌,老刑警劉巖训枢,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件托修,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肮砾,警方通過查閱死者的電腦和手機(jī)诀黍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門袋坑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仗处,“玉大人眯勾,你說我怎么就攤上這事∑攀模” “怎么了吃环?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)洋幻。 經(jīng)常有香客問我郁轻,道長(zhǎng),這世上最難降的妖魔是什么文留? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任好唯,我火速辦了婚禮,結(jié)果婚禮上燥翅,老公的妹妹穿的比我還像新娘骑篙。我一直安慰自己,他們只是感情好森书,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布靶端。 她就那樣靜靜地躺著,像睡著了一般凛膏。 火紅的嫁衣襯著肌膚如雪杨名。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天猖毫,我揣著相機(jī)與錄音台谍,去河邊找鬼。 笑死吁断,一個(gè)胖子當(dāng)著我的面吹牛典唇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胯府,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼介衔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了骂因?” 一聲冷哼從身側(cè)響起炎咖,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寒波,沒想到半個(gè)月后乘盼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俄烁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年绸栅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片页屠。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粹胯,死狀恐怖蓖柔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情风纠,我是刑警寧澤况鸣,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站竹观,受9級(jí)特大地震影響镐捧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜臭增,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一懂酱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧誊抛,春花似錦玩焰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至并炮,卻和暖如春默刚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逃魄。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工荤西, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伍俘。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓邪锌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親癌瘾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子觅丰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • ES6 引入了一種新的原始數(shù)據(jù)類型Symbol,表示獨(dú)一無二的值妨退。它是 JavaScript 語(yǔ)言的第七種數(shù)據(jù)類型...
    markpapa閱讀 189評(píng)論 0 1
  • 1.屬性的簡(jiǎn)潔表示法 允許直接寫入變量和函數(shù) 上面代碼表明妇萄,ES6 允許在對(duì)象之中,直接寫變量咬荷。這時(shí)冠句,屬性名為變量...
    雨飛飛雨閱讀 1,136評(píng)論 0 3
  • 三,字符串?dāng)U展 3.1 Unicode表示法 ES6 做出了改進(jìn)幸乒,只要將碼點(diǎn)放入大括號(hào)懦底,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,537評(píng)論 0 8
  • 我們?cè)诳磿倪^程中丐重,經(jīng)常遇到一些優(yōu)美的文字,但是苦于文字篇幅太長(zhǎng)拱层,打字輸入到電腦又太累,僅僅拍照又不方便將來的查找...
    Alex_Cui閱讀 17,197評(píng)論 2 4
  • 現(xiàn)在距離11月28日還有約一個(gè)小時(shí),看過我之前幾篇文字的盆友都知道我自稱追星族掺栅。從我來簡(jiǎn)書立下flag之時(shí)烙肺,我就告...
    Holly喜璽子閱讀 1,132評(píng)論 7 16