ES6 符號
簡介
在 ES6 的所有新特性中,Symbols 可能是我最感興趣的特性之一。我從來都不是 Ruby 開發人員,所以在實踐中我從未真正見過或使用過這些原始類型。這是一個有趣的概念,我將在本文中深入探討要點。
ES6 符號
那麼,究竟什麼是 JavaScript 符號?它是 ES6 中引入的一種新的獨特、不可變的原始數據類型,最初是為了提供私有屬性。
var sym = Symbol();
typeof sym; // Returns "symbol"
符號可用於訪問對象屬性,就像字符串一樣:
var obj = {};
var sym = Symbol();
obj[sym] = "a";
console.log(obj[sym]); // Prints "a"
這裡的主要區別是 sym
訪問的屬性 如果迭代或 stringify
不會出現在對像中 'd。例如:
var obj = {};
var sym = Symbol();
obj['hi'] = "bye";
obj[sym] = "a";
console.log(obj); // Prints "{hi: 'bye'}"
for (var i in obj) {
console.log(i); // Prints "hi"
}
console.log(JSON.stringify(obj)); // Prints {"hi":"bye"}
所以,如你所見,only 您可以使用原始符號對象訪問“符號化”屬性的方式,否則您甚至不知道該屬性存在。所以這意味著我們可以使用 Symbols 最終在 JavaScript 中擁有私有屬性,對嗎?沒有。事實證明,符號已從原始規範嚴重降級(出於我不知道的原因),並且不能用於可靠地創建私有屬性。可以通過 Object.getOwnPropertySymbols
訪問對象的符號 ,從而將它們公開給所有人看。
var obj = {};
var sym = Symbol();
obj['hi'] = "bye";
obj[sym] = "a";
Object.getOwnPropertySymbols(obj); // Returns [ Symbol() ]
提醒一句,很多人仍然認為 JS 符號為對象提供私有屬性,因此請小心您在論壇和 Stack Overflow 上閱讀和相信的內容。希望一旦 ES6 變得更加主流,這些誤解將得到糾正。
您可能還會看到許多將符號傳遞給可選字符串的示例,如下所示:
var sym = Symbol("foo");
此描述符嚴格用於調試目的,不影響符號的唯一性。為了更清楚地說明這一點,這裡有一個例子:
Symbol("foo") === Symbol("foo"); // Evaluates to false
var sym = Symbol("foo");
console.log(sym.toString()); // Prints "Symbol(foo)"
全球範圍
重要的是要意識到使用 Symbol()
函數不會創建在全局範圍內可用的全局符號。該符號仍然特定於使用它的對象。但是,您可以使用 Symbol.for()
創建全局符號 和 Symbol.keyFor()
從全局符號註冊表中獲取和設置符號。
Symbol.for(key)
使用給定鍵(字符串)搜索現有符號,如果找到則返回它。如果未找到該符號,則使用給定鍵在全局註冊表中創建一個新符號,然後返回。
免費電子書:Git Essentials
查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!
Symbol.for("foo"); // Creates a new global symbol
var sym = Symbol.for("foo"); // Retrieves the already created symbol
不同於 Symbol([description])
, 指定 Symbol.for(key)
中的鍵 會 每次返回相同的符號,所以:
Symbol.for("bar") === Symbol.for("bar"); // Evaluates to true
Symbol("bar") === Symbol("bar"); // Evaluates to false
Symbol.keyFor(sym)
與 Symbol.for(key)
本質上相反 ,而不是傳遞一個鍵來獲取一個符號,而是傳遞一個符號來獲取一個鍵。
var sym = Symbol.for("foo"); // Creates new global symbol
console.log(Symbol.keyFor(sym)); // Prints "foo"
結論
儘管 JavaScript 符號是一個新的並且有些有趣的想法,但我懷疑它們在沒有私有屬性保證的情況下是否有用。有些人建議他們將有利於避免命名衝突,這可能會有所幫助,但我相信如果不提供真正的私有屬性,他們的真正潛力將無法實現。我們將在未來的更新中看到事情的進展。
您如何看待符號?您發現它們在哪些方面有用?請在評論中告訴我們!