ES6 Symbol

為啥需要 Symbol

ES5 里面對象的屬性名都是字符串,如果你需要使用人提供的對象,你對這個(gè)對象有哪些屬性也不是很清楚,但又想為這個(gè)對象新增一些屬性显设,那么你新增的屬性名就很可能和原來的屬性名發(fā)送沖突,顯然我們是不希望這種情況發(fā)生的惦蚊。所以,我們需要確保每個(gè)屬性名都是獨(dú)一無二的,這樣就可以防止屬性名的沖突了屈溉。因此, ES6 里就引入了 Symbol ,用它來產(chǎn)生一個(gè)獨(dú)一無二的值泼返。

Symbol 是什么

Symbol 實(shí)際上是 ES6 引入的一種原始數(shù)據(jù)類型,除了 Symbol , JavaScript 還有其他 5 種數(shù)據(jù)類型,分別是 Undefined, Null. Boolean, String, Number, 對象 ,這 5 種數(shù)據(jù)類型都是 ES5 中就有的最仑。

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

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

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

Symbol 函數(shù)不能用 new

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

        let sym = new Symbol();
        console.log(sym); // Uncaught TypeError: Symbol is not a constructor

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

字符串作為參數(shù)

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

        let s1 = Symbol('s1');
        let s2 = Symbol('s2');
        let s3 = Symbol('s3'); 

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

1.給 Symbol 函數(shù)加了參數(shù)之后,控制臺(tái)輸出的時(shí)候可以區(qū)分到底是哪一個(gè)值;

  1. Symbol 函數(shù)的參數(shù)只是對當(dāng)前 Symbol 值的描述,因此相同參數(shù)的Symbol 函數(shù)返回值是不相等的;
對象作為參數(shù)

如果 Symbol 函數(shù)的參數(shù)是一個(gè)對象,就會(huì)調(diào)用該對象的 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); // 報(bào)錯(cuò)

Symbol 作屬性名

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

        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,使用對象的 Symbol 值作為屬性名時(shí),獲取相應(yīng)的屬性值不能用點(diǎn)運(yùn)算符;

2.如果用點(diǎn)運(yùn)算符來給對象的屬性賦 Symbol 類型的值,實(shí)際上屬性名會(huì)變成一個(gè)字符串,而不是一個(gè) Symbol 值;

3,在對象內(nèi)部,使用 Symbol 值定義屬性時(shí), Symbol 值必須放在方括號(hào)之中,否則只是一個(gè)字符串。

Symbol值作為屬性名的遍歷

使用 for.infor..of都無法逸歷到 Symbol 值的屬性, Symbol 值作為對象的屬性名,也無法通過 Object.keys() 止剖、Object.getOwnPropertyNames() 來獲取了。

但是,不用擔(dān)心,這種平常的需求肯定是會(huì)有解決辦法的落君。

我們可以使用Object.getownPropertySymbols() 方法獲取一個(gè)對象上的 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 值作為對象屬性的名稱時(shí),不會(huì)被常規(guī)方法遍歷到這一特性,可以為對象定義一些非私有的但是又希望只有內(nèi)部可用的方法绎速。

只能拿到 String 類型的屬性名
Object.getOwnPropertyNames(testObject)
Object.keys(testObject)

只能拿到 Symbol 類型的屬性名
Object.getOwnpropertySymbols(testObject)

能拿到對象 任何類型 的屬性名
Reflect.ownKeys(testObject)

Symbol.for() 和 Symbol.keyFor()

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

        let s1 = Symbol('s1');
        let s2 = Symbol('s2');

        let s3 = Symbol.for('s1'); // Symbol(s1)
        let s4 = Symbol.for('s2'); // Symbol(s2)

        let s11 = Symbol.keyFor(s1); // undefined 
        let s33 = Symbol.keyFor(s3); // s1

        console.log(s11); // undefined 
        console.log(s33); // s1 

Symbol.for() 函數(shù)要接受一個(gè)字符串作為參數(shù),先搜索有沒有以該參數(shù)作為名稱的 Symbol 值,如果有,就直接返回這個(gè) Symbol 值,否則就新建并返回一個(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.replfice.
Symbol.search,
Symbol.split,
Symbol.iterator
Symbol.toPrimitive,
Symbol.toStringTag,
Symbol.unscopables
等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萌京,一起剝皮案震驚了整個(gè)濱河市雁歌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌知残,老刑警劉巖靠瞎,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異求妹,居然都是意外死亡乏盐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門制恍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來父能,“玉大人,你說我怎么就攤上這事净神『瘟撸” “怎么了溉委?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長岔霸。 經(jīng)常有香客問我薛躬,道長,這世上最難降的妖魔是什么呆细? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任型宝,我火速辦了婚禮,結(jié)果婚禮上絮爷,老公的妹妹穿的比我還像新娘趴酣。我一直安慰自己,他們只是感情好坑夯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布岖寞。 她就那樣靜靜地躺著,像睡著了一般柜蜈。 火紅的嫁衣襯著肌膚如雪仗谆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天淑履,我揣著相機(jī)與錄音隶垮,去河邊找鬼。 笑死秘噪,一個(gè)胖子當(dāng)著我的面吹牛狸吞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播指煎,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蹋偏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了至壤?” 一聲冷哼從身側(cè)響起威始,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎像街,沒想到半個(gè)月后字逗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宅广,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年葫掉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跟狱。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡俭厚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出驶臊,到底是詐尸還是另有隱情挪挤,我是刑警寧澤叼丑,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站扛门,受9級特大地震影響鸠信,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜论寨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一星立、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧葬凳,春花似錦绰垂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昌简,卻和暖如春占业,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纯赎。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工谦疾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人址否。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓餐蔬,卻偏偏與公主長得像碎紊,于是被迫代替她去往敵國和親佑附。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345