詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表_第1頁
詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表_第2頁
詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表_第3頁
詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表_第4頁
詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第詳解JavaScript的Symbol類型、隱藏屬性、全局注冊表目錄Symbol類型的使用Symbol簡介Symbol類型的描述Symbol不會隱式轉(zhuǎn)字符串Symbol類似作為對象的屬性鍵創(chuàng)建Symbol鍵forin中被跳過隱藏自定義屬性Symbol全局注冊表系統(tǒng)Symbol總結(jié)

Symbol類型的使用

在前文《JavaScript的8種數(shù)據(jù)類型》中,我們已經(jīng)簡單的介紹過了JavaScript的Symbol類型,下面對其使用方法和使用場景做一個簡單的介紹。

Symbol簡介

Symbol類型是JavaScript中的一種特殊的類型,特殊在所有的Symbol類型值都互不相同。我們可以使用Symbol來表示唯一的值,下面是創(chuàng)建Symbol對象的案例:

letid=Symbol();

這樣我們就創(chuàng)建了一個Symbol類型的值,并把這個值存儲在了變量id中。

Symbol類型的描述

我們在創(chuàng)建一個Symbol類型變量的時候,可以在參數(shù)中傳入一些秒屬性的字符串,用于描述這個變量的用途信息。

例如:

letid1=Symbol('狂拽酷炫吊炸天的小明的id');

letid2=Symbol('低調(diào)奢華有內(nèi)涵的婷婷的id');

Symbol類型在任何時候都是不同的,即使他們擁有相同的描述信息,描述只是一個標簽,除此之外就沒有別的用途了,例如:

letid1=Symbol('id');

letid2=Symbol('id');

console.log(id1==id2);//false

這個標簽存在的意義,個人認為和Symbol不能直觀的看到內(nèi)部具體值的特性有關(guān),通過添加一個描述信息,讓我們對變量的用途有更直觀的了解。

Symbol不會隱式轉(zhuǎn)字符串

JavaScript中的大多數(shù)類型都可以直接轉(zhuǎn)換成字符串類型輸出,所以我們不能直觀的看到它的值到底是什么,例如我們可以直接用alert(123)把數(shù)字123轉(zhuǎn)換成字符串彈出。

但是Symbol類型比較特殊,它不能直接轉(zhuǎn)換,例如:

letid=Symbol();

alert(id);//報錯,不能把Symbol類型轉(zhuǎn)為字符串

JavaScript中的Symbol類型不能轉(zhuǎn)成字符串是由于其內(nèi)在的防治語言混亂的語言保護機制,因為字符串和Symbol在本質(zhì)上有著區(qū)別,不應(yīng)該將其中一個轉(zhuǎn)換成另一個。

試想一下,如果Symbol可以轉(zhuǎn)為字符串,那么它就變成了一個生成獨一無二字符串的函數(shù),就不再具備獨立數(shù)據(jù)類型的必要。

如果我們真的想知道Symbol變量的值,我們可以使用.toString()方法,如下所示:

letid=Symbol('thisisidentification');

console.log(id.toString());//Symbol(thisisidentification);

或者使用.description屬性,獲取描述信息:

letid=Symbol('加油,奧利給');

console.log(id.description);//加油,奧利給”

Symbol類似作為對象的屬性鍵

根據(jù)JavaScript的規(guī)范,只有兩種類型的值可以作為對象的屬性鍵:

字符串Symbol

如果使用其他類型,則會隱式的轉(zhuǎn)為字符串類型。對象的鍵在前面的章節(jié)有詳細的介紹,這里不再重復(fù)。

創(chuàng)建Symbol鍵

將Symbol作為鍵值有兩種方法:

例1:

letid=Symbol('id');

letuser={};

user[id]='idvalue';//添加Symbol鍵

console.log(user[id]);//idvalue

例2:

letid=Symbol('id');

letuser={

[id]:'idvalue',//注意這里的方括號

console.log(user[id]);

以上兩個案例展示了在對象中插入Symbol類型作為鍵的用法,需要注意的是,在訪問屬性時需要使用obj[id]而不是obj.id,因為obj.id代表的是obj[id]。

如果我們使用Symbol作為對象的鍵會有什么效果呢?

forin中被跳過

Symbol非常明顯的一個特征是,如果對象中使用Symbol作為鍵,那么使用forin語句是訪問不到Symbol類型的屬性的。

舉個例子:

letid=Symbol('id');

letuser={

name:'xiaoming',

[id]:'id',

for(letkeyinuser)console.log(user[key]);

執(zhí)行以上代碼,得到以下結(jié)果:

xiaoming

可以發(fā)現(xiàn),[id]對象的值沒有被打印出來,說明在對象屬性列表中,使用forin會自動忽略Symbol類型的鍵。

同樣的,Object.keys(user)也會忽略所有的Symbol類型的鍵。

這樣的特性能帶來非常有用的效果,例如我們可以創(chuàng)建只能自己能用的屬性。

雖然我們沒有辦法直接獲取到Symbol鍵,但是Object.assign方法能夠復(fù)制所有的屬性:

letid=Symbol();

letobj={

[id]:'123'

letobj2=Object.assign({},obj);

console.log(obj2[id]);

這并不影響Symbol的隱藏屬性,因為復(fù)制后的對象仍然無法獲取Symbol鍵。

隱藏自定義屬性

由于Symbol既不能直接轉(zhuǎn)為字符串,我們沒有辦法直觀的獲得它的值,又不能通過forin獲得對象的Symbol屬性,也就是說,如果沒有Symbol變量本身,我們就沒有辦法獲得對象內(nèi)部的對應(yīng)屬性。

因此,通過Symbol類型的鍵值,我們可以隱藏屬性,這些屬性只能我們自己訪問,其他人都看不到我們的屬性。

舉個例子:

我們在開發(fā)的過程中,需要和同事張三合作,而這個張三創(chuàng)建了一個非常好用的工具Tool,Tool是一個對象類型,我們想白嫖張三的Tool,并在此基礎(chǔ)上添加一些自己的屬性。

我們就可以通過添加Symbol類型的鍵:

lettool={//張三寫好了的Tool

usage:"Candoanything",

letname=Symbol("Mytoolobj");

tool[name]="Thisismytool";

console.log(tool[name]);

以上示例展示了如何在別人寫好的對象上添加自己的屬性,那么為什么要使用Symbol類型而不是常規(guī)的字符串呢?

原因如下:

對象tool是別人寫好的代碼,原則上我們不應(yīng)該去修改別人的代碼,這樣會造成風險;避免命名沖突,我們直接使用字符串很有可能會和別人原有的屬性鍵沖突,造成嚴重的后果;使用Symbol永遠不會發(fā)生命名沖突,因為Symbol都是不同的;別人無法訪問Symbol類型的鍵,相當于不會和別人的代碼沖突;

錯誤示范:

如果我們不使用Symbol類型,很可能出現(xiàn)以下情況:

lettool={//張三寫好了的Tool

usage:"Candoanything",

tool.usage="BoomBoom";

console.log(tool.usage);

以上代碼由于重復(fù)使用usage,從而重寫了原屬性,會造成對象原功能異常。

Symbol全局注冊表

所有的Symbol變量都是不同的,即使他們有用相同的標簽(描述)。

有些時候,我們希望通過一個字符串名稱(標簽),訪問同一個Symbol對象,例如我們在代碼的不同地方訪問相同的Symbol。

JavaScript會維護一個全局的Symbol注冊表,我們可以通過向注冊表中插入Symbol對象,并為對象起一個字符串名稱訪問該對象。

向注冊表插入或者讀取Symbol對象需要使用Symbol.for(key)方法,如果注冊表中有名為key的對象,就返回該對象,否則就插入新對象再返回。

舉個例子:

letid1=Symbol.for('id');//注冊表內(nèi)沒有名為id的Symbol,創(chuàng)建并返回

letid2=Symbol.for('id');//注冊表內(nèi)已有名為id的Symbol,直接返回

console.log(id1===id2);//true

我們通過Symbol.for(key)就能以全局變量的方式使用Symbol對象,并使用一個字符串標記對象的名字。

相反的,我們還可以使用Symbol.keyFor(Symbol)反向的從對象獲取名稱。

舉個例子:

letid=Symbol.for('id');//注冊表內(nèi)沒有名為id的Symbol,創(chuàng)建并返回

letname=Symbol.keyFor(id);

console.log(name);//id

Symbol.keyFor()函數(shù)只能用在全局Symbol對象上(使用Symbol.for插入的對象),如果用在非全局對象上,就會返回undefined。

舉個例子:

letid=Symbol('id');//局部Symbol

letname=Symbol.keyFor(id);

console.log(name);//undefined

系統(tǒng)Symbol

JavaScript有許多系統(tǒng)Symbol,例如:

Symbol.hasInstanceSymbol.iteratorSymbol.toPrimitive

它們各有用途,我們在后面的會逐步介紹道這些獨特的變量。

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論