成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Symbol 類型

NotFound / 749人閱讀

摘要:為此,存在一個(gè)全局注冊(cè)表。該調(diào)用會(huì)檢查全局注冊(cè)表,如果有一個(gè)描述為的,則返回該,否則將創(chuàng)建一個(gè)新,并通過給定的將其存儲(chǔ)在注冊(cè)表中。例如從全局注冊(cè)表中讀取如果該不存在,則創(chuàng)建它再次讀取相同的注冊(cè)表內(nèi)的稱為全局。

Symbol 類型

根據(jù)規(guī)范,對(duì)象的屬性鍵只能是 String 類型或者 Symbol 類型。不是 Number,也不是 Boolean,只有 String 或 Symbol 這兩種類型。

到目前為止,我們只見過 String?,F(xiàn)在我們來看看 Symbol 能給我們帶來什么好處。

Symbol

"Symbol" 值表示唯一的標(biāo)識(shí)符。

可以使用 Symbol() 來創(chuàng)建這種類型的值:

// id 是 symbol 的一個(gè)實(shí)例化對(duì)象
let id = Symbol();

我們可以給 Symbol 一個(gè)描述(也稱為 Symbol 名),這對(duì)于調(diào)試非常有用:

// id 是描述為 "id" 的 Symbol
let id = Symbol("id");

Symbol 保證是唯一的。即使我們創(chuàng)建了許多具有相同描述的 Symbol,它們的值也是不同。描述只是一個(gè)不影響任何東西的標(biāo)簽。

例如,這里有兩個(gè)描述相同的 Symbol —— 它們不相等:

let id1 = Symbol("id");
let id2 = Symbol("id");

*!*
alert(id1 == id2); // false
*/!*

如果您熟悉 Ruby 或者其他有 "Symbol" 的語言 —— 別被誤導(dǎo)。JavaScript 的 Symbol 與眾不同。

JavaScript 中的大多數(shù)值都支持 string 的隱式轉(zhuǎn)換。例如,我們可以 `alert` 任何值,這會(huì)起作用。Symbol 是特別的,它無法自動(dòng)轉(zhuǎn)換。

例如,這個(gè) `alert` 將會(huì)顯示錯(cuò)誤:

let id = Symbol("id");
!
alert(id); // 類型錯(cuò)誤:無法將 Symbol 值轉(zhuǎn)換為 String。
/!

如果我們真的想顯示一個(gè) Symbol,我們需要在它上面調(diào)用 `.toString()`,如下所示:

let id = Symbol("id");
!
alert(id.toString()); // Symbol(id),現(xiàn)在它起作用了
/!

這是一種防止混亂的“語言保護(hù)”,因?yàn)?String 和 Symbol 有本質(zhì)上的不同,而且不應(yīng)該偶爾將它們相互轉(zhuǎn)化。
“隱藏”屬性

Symbol 允許我們創(chuàng)建對(duì)象的“隱藏”屬性,代碼的任何其他部分都不能偶爾訪問或重寫這些屬性。

例如,如果我們想存儲(chǔ) object user 的“標(biāo)識(shí)符”,我們可以使用 Symbol 作為它的鍵:

let user = { name: "John" };
let id = Symbol("id");

user[id] = "ID Value";
alert( user[id] ); // 我們可以使用 Symbol 作為鍵來訪問數(shù)據(jù)。

在 string "id" 上使用 Symbol("id") 有什么好處?

我們用更深入一點(diǎn)的示例來說明這一點(diǎn)。

假設(shè)另一個(gè)腳本希望 user 中有它自己的 "id" 屬性可以操作。這可能是另一個(gè) JavaScript 庫,所以這些腳本完全不知道對(duì)方是誰。

然后該腳本可以創(chuàng)建自己的 Symbol("id"),如下所示:

// ...
let id = Symbol("id");

user[id] = "Their id value";

不會(huì)沖突,因?yàn)?Symbol 總是不同的,即使它們有相同的名稱。

現(xiàn)在請(qǐng)注意,如果我們使用 String "id" 而不是用 symbol,那么就會(huì)出現(xiàn)沖突:

let user = { name: "John" };

//我們的腳本使用 "id" 屬性。
user.id = "ID Value";

// ...如果之后另一個(gè)腳本為其目的使用 "id"...

user.id = "Their id value"
// 砰!無意中重寫了 id!他不是故意傷害同事的,而是這樣做了!
字面量中的 Symbol

如果我們要在 object 字面量中使用 Symbol,則需要方括號(hào)。

就像這樣:

let id = Symbol("id");

let user = {
  name: "John",
*!*
  [id]: 123 // 不僅僅是 "id:123"
*/!*
};

這是因?yàn)槲覀冃枰兞?id 的值作為鍵,而不是 String "id"。

Symbol 在 for..in 中被跳過

Symbolic 屬性不參與 for..in 循環(huán)。

例如:

let id = Symbol("id");
let user = {
  name: "John",
  age: 30,
  [id]: 123
};

*!*
for (let key in user) alert(key); // name, age (no symbols)
*/!*

// 被 Symbol 任務(wù)直接訪問
alert( "Direct: " + user[id] );

這是一般“隱藏”概念的一部分。如果另一個(gè)腳本或庫在我們的對(duì)象上循環(huán),它不會(huì)訪問一個(gè) Symbol 類型的屬性。

相反,Object.assign 同時(shí)復(fù)制字符串和符號(hào)屬性:

let id = Symbol("id");
let user = {
  [id]: 123
};

let clone = Object.assign({}, user);

alert( clone[id] ); // 123

這里并不矛盾,就是這樣設(shè)計(jì)的。我們的想法是當(dāng)我們克隆一個(gè) object 或合并 object 時(shí),通常希望所有屬性被復(fù)制(包括像 id 這樣的 Symbol)。

我們只能在對(duì)象中使用 string 或 symbol 作為鍵,其它類型轉(zhuǎn)換為 String。

例如,在作為屬性鍵使用時(shí),數(shù)字 `0`變成了字符串 `"0"`:

let obj = {
0: "test" // same as "0": "test"
};

//兩個(gè) alert 都訪問相同的屬性(Number 0 被轉(zhuǎn)換為 String "0")
alert( obj["0"] ); // test
alert( obj[0] ); // test (相同屬性)

全局 symbol

正如我們所看到的,通常所有的 Symbol 都是不同的,即使它們有相同的名字。但有時(shí)我們想要同一個(gè)名字的 Symbol 是相同的實(shí)體。

比如,我們希望在應(yīng)用程序的不同部分訪問相同的 Symbol "id" 屬性。

為此,存在一個(gè)全局 symbol 注冊(cè)表。我們可以在其中創(chuàng)建 Symbol 并在稍后訪問它們,它可以確保每次訪問相同名稱都會(huì)返回相同的 Symbol。

為了在注冊(cè)表中創(chuàng)建或讀取 Symbol,請(qǐng)使用 Symbol.for(key)。

該調(diào)用會(huì)檢查全局注冊(cè)表,如果有一個(gè)描述為 key 的 Symbol,則返回該 Symbol,否則將創(chuàng)建一個(gè)新 Symbol(Symbol(key)),并通過給定的 key 將其存儲(chǔ)在注冊(cè)表中。

例如:

// 從全局注冊(cè)表中讀取
let id = Symbol.for("id"); // 如果該 Symbol 不存在,則創(chuàng)建它

// 再次讀取
let idAgain = Symbol.for("id");

// 相同的 Symbol
alert( id === idAgain ); // true

注冊(cè)表內(nèi)的 Symbol 稱為全局 Symbol。如果我們想要一個(gè)應(yīng)用程序范圍內(nèi)的 Symbol,可以在代碼中隨處訪問 —— 這就是它們的用途。

在一些編程語言中,例如 Ruby,每個(gè)名稱都有一個(gè) symbol。

在 JavaScript 中,我們應(yīng)該用全局 symbol。
Symbol.keyFor

對(duì)于全局 symbol,Symbol.for(key) 不僅按名稱返回一個(gè) symbol,而且還有一個(gè)反向調(diào)用:Symbol.keyFor(sym),反過來:通過全局 symbol 返回一個(gè)名稱。

例如:

let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// 從 symbol 中獲取 name
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id

Symbol.keyFor 在內(nèi)部使用全局 symbol 注冊(cè)表來查找 symbol 的鍵。所以它不適用于非全局 symbol。如果 symbol 不是全局的,它將無法找到它并返回 undefined。

例如:

alert( Symbol.keyFor(Symbol.for("name")) ); // name, 全局 Symbol

alert( Symbol.keyFor(Symbol("name2")) ); // undefined, 參數(shù)不是一個(gè)全局 Symbol
系統(tǒng) Symbol

JavaScript 內(nèi)部存在很多“系統(tǒng)” Symbol,我們可以使用它們來微調(diào)對(duì)象的各個(gè)方面。

它們列在熟悉的 Symbol 表的規(guī)范中:

Symbol.hasInstance

Symbol.isConcatSpreadable

Symbol.iterator

Symbol.toPrimitive

...等等。

例如,Symbol.toPrimitive 允許我們將對(duì)象描述為原始值轉(zhuǎn)換,我們很快就會(huì)看到它的使用。

當(dāng)我們研究相應(yīng)的語言特征時(shí),其他 Symbol 也會(huì)變得熟悉起來。

總結(jié)

Symbol 是唯一標(biāo)識(shí)符的基本類型

Symbol 使用 Symbol() 創(chuàng)建的,調(diào)用帶有一個(gè)可選的描述。

Symbol 總是不同的值,即使它們有相同的名稱。如果我們希望同名 Symbol 相等,那么我們應(yīng)該使用全局注冊(cè)表:Symbol.for(key) 返回(如果需要的話創(chuàng)建)一個(gè)以 key 作為名稱的全局 Symbol。Symbol.for 的多次調(diào)用完全返回相同的 Symbol。

Symbol 有兩個(gè)主要的使用場(chǎng)景:

“隱藏” 對(duì)象屬性。如果需要將屬性添加到 “屬于” 另一個(gè)腳本或庫的對(duì)象中,則可以創(chuàng)建 Symbol 并將其用作屬性鍵。Symbol 屬性不出現(xiàn)在 for..in中,因此不會(huì)無心列出。另外,它不會(huì)被直接訪問,因?yàn)榱硪粋€(gè)腳本沒有我們的符號(hào),所以它不會(huì)不小心干預(yù)它的操作。

因此我們可以使用 Symbol 屬性“秘密地”將一些東西隱藏到我們需要的對(duì)象中,但其他人不會(huì)以對(duì)象屬性的形式看到它。

JavaScript 使用了許多系統(tǒng) Symbol,這些 Symbol 可以作為 Symbol.* 訪問。我們可以使用它們來改變一些內(nèi)置行為。例如,在本教程的后面部分,我們將使用 Symbol.iterator 來迭代,Symbol.toPrimitive 來設(shè)置對(duì)象原始值的轉(zhuǎn)換等等。

從技術(shù)上說,Symbol 不是 100% 隱藏的。有一個(gè)內(nèi)置方法 Object.getOwnPropertySymbols(obj) 允許我們獲取所有的 Symbol。還有一個(gè)名為 Reflect.ownKeys(obj) 返回所有鍵,包括 Symbol。所以它們不是真正的隱藏。但是大多數(shù)庫、內(nèi)置方法和語法結(jié)構(gòu)都遵循一個(gè)共同的協(xié)議。而明確調(diào)用上述方法的人可能很清楚他在做什么。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109372.html

相關(guān)文章

  • 通俗易懂理解ES6 - ES6的變量類型及Iterator

    摘要:迭代器在原有的數(shù)據(jù)結(jié)構(gòu)類型上新增了兩種類型,我們?cè)谑褂玫臅r(shí)候還可以通過自由組合的形式使用這些結(jié)構(gòu)類型達(dá)到自己想要的數(shù)據(jù)結(jié)構(gòu),這就需要一種統(tǒng)一的接口機(jī)制供我們調(diào)用處理不同的數(shù)據(jù)結(jié)構(gòu)。 引言 萬丈高樓平地起,欲練此功,必先打好基本功: ) 在了解 ES6 新增的變量類型前,我們必須先知道 JavaScript 在ES6之前,有如下六種基本數(shù)據(jù)類型:Null、Undefined、Number...

    Keven 評(píng)論0 收藏0
  • ES6 Symbol - 基本使用方法

    摘要:但是,前來提到的個(gè)方法都不支持屬性,為了保持原有的功能,新增了一個(gè)方法來檢索類型的屬性接下來看一下式例以上,就是關(guān)于的基本使用方法。 ES6新增了一個(gè)基本數(shù)據(jù)類型:Symbol,至此ECMAScript的基本數(shù)據(jù)類型就有了6種:字符串,數(shù)字,布爾,null,undefined,Symbol。關(guān)于Symbol,我打算寫2篇文章來提取一下比較重要的知識(shí)點(diǎn),這篇是第一篇,主要講Symbol的...

    paney129 評(píng)論0 收藏0
  • ES6學(xué)習(xí)筆記之Symbol

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

    leo108 評(píng)論0 收藏0
  • 《深入理解ES6》筆記——SymbolSymbol屬性(6)

    摘要:設(shè)置對(duì)象屬性只讀。提供了一個(gè)注冊(cè)機(jī)制,當(dāng)你注冊(cè)之后,就能在全局共享注冊(cè)表里面的。的注冊(cè)表和對(duì)象表很像,都是結(jié)構(gòu),只不過這個(gè)是值。語法只有一個(gè)參數(shù),返回的是從注冊(cè)表獲取全局共享的注意如果要防止命名重復(fù)問題,可以加上前綴。 還記得對(duì)象Object嗎? let obj = { a: 1 } 對(duì)象的格式: Object { key: value } 在ES5的時(shí)代,對(duì)象的key只能...

    heartFollower 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(六)--JavaScript類型有哪些你不知道的細(xì)節(jié)?

    摘要:的碼點(diǎn)被稱為基本字符區(qū)域。關(guān)于的介紹,我準(zhǔn)備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對(duì)象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數(shù)前不能使用命令,否則會(huì)報(bào)錯(cuò)。 筆記說明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過程的一些要點(diǎn)筆記以及感悟,完...

    Lsnsh 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<