91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript 中的 Symbols 怎么用

發布時間:2020-06-07 07:03:39 來源:網絡 閱讀:201 作者:wx5d721be2ee1ef 欄目:編程語言

為了防止屬性名沖突, JavaScript 介紹了一種?symbols?的類型。在 2015 - 2019 中,symbols 提供一種方法去模擬私有屬性。

簡介

創建 symbol 最簡單的方式是調用?Symbol()?方法。有兩個關鍵屬性使得 symbols 變得特殊:

  1. Symbols 可以用于對象 key。只有字符串和 symbol 可以被用于對象 key。

  2. 任何兩個 sybmols 都不相等

const?symbol1?=?Symbol();?const?symbol2?=?Symbol();?symbol1?===?symbol2;?//?false?const?obj?=?{};?obj[symbol1]?=?'Hello';?obj[symbol2]?=?'World';?obj[symbol1];?//?'Hello'?obj[symbol2];?//?'World'?復制代碼

盡管 symbol() 看起來是個對象,實際上它也屬于?7 種基本類型。對 Symbol 使用 new 操作符會導致一個錯誤。

const?symbol1?=?Symbol();?typeof?symbol1;?//?'symbol'?symbol1?instanceof?Object;?//?false?//?Throws?"TypeError:?Symbol?is?not?a?constructor"?new?Symbol();?復制代碼

描述符

Symbol 方法使用單個字符串參數當做描述符。Symbol 的描述符只是用于 debug 的目的。描述符在 symbol 調用 toString 的時候出現。然而,兩個相同描述符的 symbol 也是不相等的。

const?symbol1?=?Symbol('my?symbol');?const?symbol2?=?Symbol('my?symbol');?symbol1?===?symbol2;?//?false?console.log(symbol1);?//?'Symbol(my?symbol)'?復制代碼

通常情況下,除非你有合適的理由,不然一般不建議使用全局 symbol 注冊,這么做有可能導致命名沖突。

命名沖突

JavaScript 中的第一個內置 symbol 是 Symbol.iterator。一個有 Symbol.iterator 方法當做迭代的對象。也就意味著。你可以使用這個對象作為循環的右操作符。

比如獲取斐波那契數列:

const?fibonacci?=?{???[Symbol.iterator]:?function*()?{?????let?a?=?1;?????let?b?=?1;?????let?temp;?????yield?b;?????while?(true)?{???????temp?=?a;???????a?=?a?+?b;???????b?=?temp;???????yield?b;?????}???}?};?//?Prints?every?Fibonacci?number?less?than?100?for?(const?x?of?fibonacci)?{???if?(x?>=?100)?{?????break;???}???console.log(x);?}?復制代碼

為什么 Symbol.iterator 是 symbol 而不是 string? 假設不使用 Symbol.iterator,迭代名定義為一個字符串屬性的 iterator。也就是說,假設有一個可迭代的類,如下:

class?MyClass?{???constructor(obj)?{?????Object.assign(this,?obj);???}???iterator()?{?????const?keys?=?Object.keys(this);?????let?i?=?0;?????return?(function*()?{???????if?(i?>=?keys.length)?{?????????return;???????}???????yield?keys[i++];?????})();???}?}?復制代碼

MyClass 允許你迭代對象 keys。但是上面的類有個潛在的錯誤。假設用戶故意給對象傳遞一個 iterator 的屬性。比如:

const?obj?=?new?MyClass({?iterator:?'not?a?function'?});?復制代碼

這樣的話,迭代就會失效。JavaScript 在你使用 for/of 迭代時,會拋出一個錯誤 obj is not iterable。這是因為上面的代碼覆蓋了類中的迭代屬性。這是類似原型污染的安全問題。在想當然拷貝用戶數據的時候容易發生這樣的問題,尤其是?proto?和 constructor 這樣的屬性。

關鍵模式在于 symbol 可以清楚的分割用戶數據和對象數據。由于符號無法用JSON表示,因此不存在將數據傳遞到具有錯誤 Symbol.iterator 屬性的 Express API 的風險。 在將用戶數據與內置函數和方法(如Mongoose模型)混合的對象中,可以使用符號來確保用戶數據不會與內置功能沖突。

私有屬性

既然任意兩個 symbol 都不相等,symbol 可以方便的模擬 JavaScript 中的私有屬性。 Symbols 不會在?Object.key(),中出現,因為除非你明確 export 一個 symbol,沒有任何代碼可以訪問到這個屬性,除非使用 Object.getOwnPropertySymbols() 方法。

function?getObj()?{???const?symbol?=?Symbol('test');???const?obj?=?{};???obj[symbol]?=?'test';???return?obj;?}?const?obj?=?getObj();?Object.keys(obj);?//?[]?//?Unless?you?explicitly?have?a?reference?to?the?symbol,?you?can't?access?the?//?symbol?property.?obj[Symbol('test')];?//?undefined?//?You?can?still?get?a?reference?to?the?symbol?using?`getOwnPropertySymbols()`?const?[symbol]?=?Object.getOwnPropertySymbols(obj);?obj[symbol];?//?'test'?復制代碼

Symbols 作為私有屬性方便的一點是,它不會在 JSON.stringify() 中出現。

最后

Symbols 處理對象內部狀態保證用戶數據和程序數據分離是很不錯的一個工具。使用 symbols 就不需要再加上各種前綴表示程序狀態。下次可以試試 symbol。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙江县| 永泰县| 华容县| 北宁市| 宝清县| 汾阳市| 江阴市| 突泉县| 通榆县| 镇巴县| 隆安县| 将乐县| 迁安市| 凤凰县| 四会市| 阳高县| 施甸县| 晋城| 巩留县| 连平县| 北辰区| 仁化县| 湟源县| 尉氏县| 志丹县| 巴彦淖尔市| 南皮县| 永春县| 崇义县| 肥城市| 九江县| 宣城市| 临泉县| 南阳市| 全州县| 郓城县| 金昌市| 土默特左旗| 承德市| 视频| 刚察县|