步遙——Symbol

1:Symbol
引入的原因:
防止在混入新屬性時馋贤,屬性名沖突

這樣對象的屬性名現(xiàn)在可以有兩種類型:一種就是字符串责球,一種就是新增的Symbol類型。凡是Symbol類型的屬性名贸典,都是獨一無二的视卢,可以保證不會和其他屬性名產(chǎn)生沖突。

含義:symbol表示獨一無二的值廊驼,是js語言的第七種數(shù)據(jù)類型

使用語法:通過Symbol函數(shù)生成 据过,Symbol函數(shù)前不能使用new命令。否則會報錯

let s = Symbol();

Symbol函數(shù)可以接受一個字符串作為參數(shù)妒挎,表示對Symbol實例的描述绳锅,主要是為了在控制臺顯示,或者轉(zhuǎn)為字符串時酝掩,比較容易區(qū)分鳞芙。
總結(jié)一句話:加描述,就是為了區(qū)分不同的symbol類型的屬性庸队,相同參數(shù)的Symbol函數(shù)的返回值是不相等的

let s = Symbol('dgsg')
let s2 = Symbol('dgsg')
s === s2 // false 相同參數(shù)的Symbol函數(shù)的返回值是不相等的

如果Symbol的參數(shù)是一個對象积蜻,就會調(diào)用該對象的toString方法,將其轉(zhuǎn)為字符串彻消,然后才生成一個Symbol值

let s = Symbol({toString(){return 'ere'}})
s // Symbol(ere)

Symbol值不能像字符串一樣參與運算竿拆,會報錯,
但是可以顯示轉(zhuǎn)為字符串

let sym = Symbol('My symbol')
String(sym) // "Symbol(My symbol)"  即便是可以顯示轉(zhuǎn)為字符串但也不能和字符串進行拼接運算
"your symbol is " + sym // TypeError: can't convert symbol to string

Symbol值可以轉(zhuǎn)為布爾值宾尚,但是不能轉(zhuǎn)為數(shù)值

2: Symbol.prototype.description
方便讀取symbol值的描述:

let sym = Symbol('My symbol')
sym.description // "My symbol"

3:作為屬性名的Symbol
由于每一個Symbol值都不相等丙笋,意味著用于對象屬性名,就能保證不會出現(xiàn)同名的屬性煌贴。對于一個對象由多個模塊構(gòu)成的情況非常有用御板。能防止某一個鍵被不小心改寫或覆蓋。
作為對象的屬性名時使用[](方括號)語法牛郑,不能使用.(點)語法怠肋,因為點運算符后面總是字符串,所以不會讀取symbol作為標(biāo)識符所指代的那個值淹朋。
Symbol類型還可以用于定義一組常量笙各,保證這組常量的值都是不相等的钉答。

const log={}
log.levels = {
DEBUG:Symbol('debug'),
INFO:Symbol('info'),
WARN:Symbol('warn')
}

常量使用Symbol的最大的好處,就是其他任何值都不可能有相同值杈抢,
Symbol值作為屬性名時数尿,該屬性還是公開屬性,不是私有屬性惶楼。

4:消除魔術(shù)字符串
魔術(shù)字符串右蹦,就是指在代碼中多次出現(xiàn),與代碼形成強耦合的某一個具體字符串或者數(shù)值歼捐,風(fēng)格良好的代碼何陆,應(yīng)該盡量消除魔術(shù)字符串,改由含義清晰的變量替代窥岩。
常用的方法是:將它寫成一個變量甲献。
由于該變量等于那個值其實并不重要宰缤,重要的是不會跟其他的屬性值沖突即可颂翼。因為消除魔術(shù)字符串就很適合使用Symbol值。

5:屬性名的遍歷:
for...in
for...of
Object.keys
Object.getOwnPropertyNames
JSON.stringify
以上都不會返回Symbol屬性名的屬性
Object.getOwnPropertySymbols會返回所有的Symbol屬性

let s={
[Symbol('d')]:'erer', //symbol值作為屬性名
[Symbol('s')](){//}, //symbol值作為函數(shù)名
c:'12'
}
Object.getOwnPropertySymbols(s) // [Symbol(d)]

另一個新的API:Reflect.ownKeys() 可以返回所有類型的鍵名慨灭,包括常規(guī)鍵名和Symbol鍵名朦乏。

Reflect.ownKeys(s) // ['c',Symbol(d)]

由于Symbol值作為鍵名,不會被常規(guī)方法遍歷得到氧骤,可以利用這個特性呻疹,為對象定義一些非私有的,但又希望只用于內(nèi)部的方法筹陵。

6:Symbol.for Symbol.keyFor
使用同一個值刽锤,Symbol.for接受一個字符串參數(shù),搜索有沒有以該參數(shù)作為名稱的Symbol值朦佩,如果有并思,就返回這個Symbol值,否則就新建一個以該字符串為名稱的Symbol值语稠,并將其注冊到全局宋彼。Symbol.for和Symbol.keyFor都是對注冊的symbol,Symbol.for會將生成的變量進行注冊仙畦,Symbol不進行注冊输涕。

let s1 = Symbol.for('sdfsf')
let s3 = Symbol.for('sdfsf')
s1 === s3 // true 表示Symbol.for('sdfsf') 直接返回了已定義的s1 并賦值給s3

Symbol.for 和Symbol都會生成Symbol值,區(qū)別是慨畸,
1:Symbol.for會被登記到全局環(huán)境中供搜索莱坎,Symbol不會。
2:Symbol.for不會每次調(diào)用返回一個新的Symbol類型的值寸士,而是先檢查給定的key是否已經(jīng)存在檐什,如果不存在才會新建一個值瞳收。而 Symbol()寫法沒有登記機制,所以每次調(diào)用都會返回一個不同的值厢汹。

Symbol.keyFor 返回一個已登記的Symbol類型值的key

Symbol.keyFor(s3) // "sdfsf"
Symbol.keyFor(s4) // undefined

Symbol.for即便是在函數(shù)內(nèi)容生成的螟深,但是也是登記到全局中,這個全局登記特性烫葬,可以用在不同的iframe或service worker中取到同一個值界弧。

7:模塊的Singleton模式
Singleton模式指的是調(diào)用一個類,任何時候返回的都是同一個實例搭综。

// mod.js
const FOO_KEY = Symbol.for('foo');

function A() {
  this.foo = 'hello';
}

if (!global[FOO_KEY]) {
  global[FOO_KEY] = new A();
}

module.exports = global[FOO_KEY];

8:內(nèi)置的Symbol值

11個內(nèi)置的Symbol值垢箕。
Symbol.hasInstance:指向一個內(nèi)部方法。當(dāng)其他對象使用instanceof運算符兑巾,判斷是否為該對象的實例時条获,會調(diào)用該方法。
Symbol.isConcatSpreadable:指向一個布爾值蒋歌,表示該對象用于Array.prototype.concat時帅掘,是否可以展開。

let arr = [1,23,4]
arr[Symbol.isConcatSpreadable] // undefined 數(shù)組默認是展開的
[5,6,7].concat(arr,0,5) //  [5, 6, 7, 1, 23, 4, 0, 5] 默認是展開的堂油,所以concat后就直接是展開的數(shù)組

let obj = {c:1,d:5}
['a','d'].concat(obj,'e') // ["a", "d", {…}, "e"] 對象是默認不展開的

Symbol.species:指向一個構(gòu)造函數(shù)修档,創(chuàng)建衍生對象時,會使用該屬性府框。

Symbol.species的作用在于吱窝,實例對象在運行過程中,需要再次調(diào)用自身的構(gòu)造函數(shù)時迫靖,會調(diào)用該屬性指定的構(gòu)造函數(shù)院峡。
它主要的用途是,有些類庫是在基類的基礎(chǔ)上修改的系宜,那么子類使用繼承的方法時照激,作者可能希望返回基類的實例,而不是子類的實例蜈首。修改父類的指向

Symbol.match:指向一個函數(shù)实抡,執(zhí)行str.match時,如果該屬性存在欢策,會調(diào)用它吆寨,返回該方法的返回值。
Symbol.replace:指向一個方法踩寇,當(dāng)該對象被String.prototype.replace方法調(diào)用時啄清,會返回該方法的返回值。
Symbol.replace方法會收到兩個參數(shù),第一個參數(shù)是replace方法正在作用的對象辣卒,上面例子是Hello掷贾,第二個參數(shù)是替換后的值,上面例子是World荣茫。

Symbol.search:指向一個方法想帅,當(dāng)該對象被String.prototype.search方法調(diào)用時,返回該方法的返回值啡莉。
Symbol.split:指向一個方法港准,當(dāng)該對象被String.prototype.split方法調(diào)用時,返回該方法的返回值咧欣。
Symbol.iterator:指向該對象的默認遍歷器方法浅缸。對象進行for...of循環(huán)時,會調(diào)用Symbol.iterator方法魄咕,返回該對象的默認遍歷器衩椒。
Symbol.toPrimitive:指向一個方法,該對象被轉(zhuǎn)為原始類型的值時哮兰,會調(diào)用這個方法毛萌,返回該對象對應(yīng)的原始類型值。
Symbol.toPrimitive被調(diào)用時奠蹬,會接受一個字符串參數(shù)朝聋,表示當(dāng)前運算的模式,一共有三種模式囤躁。
* Number:該場合需要轉(zhuǎn)成數(shù)值
* String:該場合需要轉(zhuǎn)成字符串
* Default:該場合可以轉(zhuǎn)成數(shù)值,也可以轉(zhuǎn)成字符串

Symbol.toStringTag:指向一個方法荔睹,在該對象調(diào)用Object.prototype.toString方法時狸演,如果這個屬性存在,它的返回值會出現(xiàn)在toString方法返回的字符串之中僻他,表示對象的類型宵距。也就是說,這個屬性可以用來定制[object Object]或[object Array]中的object后面的那個字符串吨拗。

({[Symbol.toStringTag]:'Foo'}.toString()) //'[object Foo]'

Symbol.unscopables:指向一個對象满哪,該對象指定使用with關(guān)鍵字時,哪些屬性會被with環(huán)境排除劝篷。設(shè)定Symbol.unscopables的屬性會被with排除哨鸭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娇妓,隨后出現(xiàn)的幾起案子像鸡,更是在濱河造成了極大的恐慌,老刑警劉巖哈恰,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件只估,死亡現(xiàn)場離奇詭異志群,居然都是意外死亡,警方通過查閱死者的電腦和手機蛔钙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門锌云,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吁脱,你說我怎么就攤上這事宾抓。” “怎么了豫喧?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵石洗,是天一觀的道長。 經(jīng)常有香客問我紧显,道長讲衫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任孵班,我火速辦了婚禮涉兽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘篙程。我一直安慰自己枷畏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布虱饿。 她就那樣靜靜地躺著拥诡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氮发。 梳的紋絲不亂的頭發(fā)上渴肉,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音爽冕,去河邊找鬼仇祭。 笑死,一個胖子當(dāng)著我的面吹牛颈畸,可吹牛的內(nèi)容都是我干的乌奇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼眯娱,長吁一口氣:“原來是場噩夢啊……” “哼礁苗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起困乒,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤寂屏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迁霎,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡吱抚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了考廉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秘豹。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖昌粤,靈堂內(nèi)的尸體忽然破棺而出既绕,到底是詐尸還是另有隱情,我是刑警寧澤涮坐,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布凄贩,位于F島的核電站,受9級特大地震影響袱讹,放射性物質(zhì)發(fā)生泄漏疲扎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一捷雕、第九天 我趴在偏房一處隱蔽的房頂上張望椒丧。 院中可真熱鬧,春花似錦救巷、人聲如沸壶熏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棒假。三九已至,卻和暖如春管怠,著一層夾襖步出監(jiān)牢的瞬間淆衷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工渤弛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甚带。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓她肯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鹰贵。 傳聞我的和親對象是個殘疾皇子晴氨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

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

  • 【ES6腳丫系列】Symbol 如果有理解不到位的地方,歡迎大家糾錯碉输。如果覺得還可以籽前,希望大家可以點個贊。 謝謝...
    吃碼小妖閱讀 700評論 0 1
  • 前言 該部分為書籍 深入理解ES6 第六章(符號與符號屬性)筆記 創(chuàng)建符號值 符號沒有字面量形式, 這在 JS 的...
    歲月靜好_不負此生閱讀 527評論 0 0
  • 前言 在 Es6 中引入了一個新的基礎(chǔ)數(shù)據(jù)類型:Symbol,對于其他基本數(shù)據(jù)類型(數(shù)字number,布爾bool...
    itclanCoder閱讀 1,335評論 0 0
  • 概述 ES5的對象屬性名都是字符串,這容易造成屬性名的沖突枝哄。比如肄梨,你使用了一個他人提供的對象,但又想為這個對象添加...
    oWSQo閱讀 529評論 1 3
  • 回憶一下JS中的原始類型:字符串型挠锥、數(shù)字型众羡、布爾型、null和undefined蓖租。 ES6中引入了第6種原始類型:...
    ___Jing___閱讀 8,670評論 2 10