ES6集合:使用地圖,設置,弱圖,弱點
本文探討了四個新的ES6集合以及它們帶來的好處。
大多數主要的編程語言都有幾種類型的數據集合。 Python有列表、元組和字典。 Java有列表、集合、映射、隊列。 Ruby有哈希和數組。到目前為止,JavaScript只有數組。對象和數組是JavaScript的得力助手。 ES6引入了四個新的數據結構,它們將增強語言的強大功能和表達能力:Map、Set、WeakSet和WeakMap。
關鍵要點
- ES6引入了四個新的數據結構:Map、Set、WeakSet和WeakMap。這些集合允許更具表達性和功能強大的JavaScript編程。
- ES6中的Map和Set是任何類型的鍵值對的集合。它們針對快速檢索進行了優化,並提供添加、刪除和循環遍歷值的方法。但是,它們對對象持有強引用,如果對像很大且不再需要,則可能代價很高。
- ES6還引入了WeakMap和WeakSet,它們類似於Map和Set,但對對象持有弱引用。這意味著當這些對像不再需要時,可以對其進行垃圾回收,這對於內存管理非常有益。
- 雖然新的ES6集合提供了更大的靈活性,但在許多情況下,JavaScript對象仍然可以用作集合。在決定是否使用對像或鍵控集合時,開發人員應考慮諸如需要動態鍵查找、值的互換性和添加或刪除鍵值對的頻率等因素。
尋找JavaScript HashMap
HashMap、字典和哈希是各種編程語言存儲鍵值對的幾種方法,這些數據結構針對快速檢索進行了優化。
在ES5中,JavaScript對象(只是具有鍵和值的屬性的任意集合)可以模擬哈希,但是使用對像作為哈希有幾個缺點。
缺點#1:ES5中的鍵必須是字符串
JavaScript對象屬性鍵必須是字符串,這限制了它們作為不同數據類型鍵值對集合的能力。當然,您可以將其他數據類型強制轉換為字符串,但這會增加額外的工作。
缺點#2:對象並非天生可迭代
對象並非設計為集合,因此沒有有效的方法來確定對像有多少屬性。 (例如,Object.keys速度很慢)。當您循環遍歷對象的屬性時,您還會獲得其原型屬性。您可以向所有對象添加可迭代屬性,但並非所有對像都旨在用作集合。您可以使用for … in循環和hasOwnProperty()方法,但這只是一個變通方法。當您循環遍歷對象的屬性時,屬性不一定會按照插入的順序檢索。
缺點#3:內置方法衝突的挑戰
對象具有內置方法,如constructor、toString和valueOf。如果將其中一個添加為屬性,則可能導致衝突。您可以使用Object.create(null)創建一個裸對象(不繼承自object.prototype),但這仍然只是一個變通方法。
ES6包含新的集合數據類型,因此不再需要使用對象並忍受它們的缺點。
使用ES6 Map集合
Map是我們將要檢查的第一個數據結構/集合。 Map是任何類型的鍵值對的集合。創建新的Map、添加/刪除值、循環遍歷鍵/值以及有效地確定其大小很容易。以下是關鍵方法:
創建映射並使用常用方法
const map = new Map(); // 创建一个新的Map map.set('hobby', 'cycling'); // 设置键值对 const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' }; // 新对象 const normalfoods = {}; // 新对象 map.set(normalfoods, foods); // 设置两个对象作为键值对 for (const [key, value] of map) { console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object] } map.forEach((value, key) => { console.log(`${key} = ${value}`); }, map); // hobby = cycling [object Object] = [object Object] map.clear(); // 清除键值对 console.log(map.size === 0); // True
在JSBin上運行此示例
使用Set集合
Set是有序的值列表,不包含重複項。 Set不是像數組那樣被索引,而是使用鍵訪問。 Set已經存在於Java、Ruby、Python和許多其他語言中。 ES6 Set與其他語言中的Set之間的一個區別是,順序在ES6中很重要(在許多其他語言中並非如此)。以下是關鍵的Set方法:
const planetsOrderFromSun = new Set(); planetsOrderFromSun.add('Mercury'); planetsOrderFromSun.add('Venus').add('Earth').add('Mars'); // 可链式方法 console.log(planetsOrderFromSun.has('Earth')); // True planetsOrderFromSun.delete('Mars'); console.log(planetsOrderFromSun.has('Mars')); // False for (const x of planetsOrderFromSun) { console.log(x); // 输入和输出顺序相同 - Mercury Venus Earth } console.log(planetsOrderFromSun.size); // 3 planetsOrderFromSun.add('Venus'); // 尝试添加重复项 console.log(planetsOrderFromSun.size); // 仍然是3,没有添加重复项 planetsOrderFromSun.clear(); console.log(planetsOrderFromSun.size); // 0
在JSBin上運行此示例
弱集合、內存和垃圾回收
JavaScript垃圾回收是一種內存管理形式,其中不再引用的對象會自動刪除,並且其資源會被回收。
Map和Set對對象的引用是強持有的,並且不允許垃圾回收。如果map/set引用不再需要的大的對象(例如已經從DOM中刪除的DOM元素),這可能會變得很昂貴。
為了解決這個問題,ES6還引入了兩個新的弱集合,稱為WeakMap和WeakSet。這些ES6集合是“弱”的,因為它們允許不再需要的對像從內存中清除。
WeakMap
WeakMap是我們介紹的第三個新的ES6集合。 WeakMap類似於普通的Map,但方法較少,並且在垃圾回收方面存在上述差異。
const aboutAuthor = new WeakMap(); // 创建新的WeakMap const currentAge = {}; // 键必须是对象 const currentCity = {}; // 键必须是对象 aboutAuthor.set(currentAge, 30); // 设置键值 aboutAuthor.set(currentCity, 'Denver'); // 键值可以是不同数据类型 console.log(aboutAuthor.has(currentCity)); // 测试WeakMap是否包含键 aboutAuthor.delete(currentAge); // 删除键
使用案例
WeakMap有幾個流行的用例。它們可以用來保持對象的私有數據私有,也可以用來跟踪DOM節點/對象。
私有數據用例
以下示例來自JavaScript專家Nicholas C. Zakas:
var Person = (function() { var privateData = new WeakMap(); function Person(name) { privateData.set(this, { name: name }); } Person.prototype.getName = function() { return privateData.get(this).name; }; return Person; }());
在這裡使用WeakMap簡化了保持對像數據私有的過程。可以引用Person對象,但是如果沒有特定的Person實例,則不允許訪問privateDataWeakMap。
DOM節點用例
Google Polymer項目在一個名為PositionWalker的代碼片段中使用WeakMap。
PositionWalker跟踪DOM子樹中的位置,作為當前節點和該節點內的偏移量。
WeakMap用於跟踪DOM節點的編輯、刪除和更改:
const map = new Map(); // 创建一个新的Map map.set('hobby', 'cycling'); // 设置键值对 const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' }; // 新对象 const normalfoods = {}; // 新对象 map.set(normalfoods, foods); // 设置两个对象作为键值对 for (const [key, value] of map) { console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object] } map.forEach((value, key) => { console.log(`${key} = ${value}`); }, map); // hobby = cycling [object Object] = [object Object] map.clear(); // 清除键值对 console.log(map.size === 0); // True
WeakSet
WeakSet是其元素在不再需要它們引用的對象時可以進行垃圾回收的Set集合。 WeakSet不允許迭代。它們的用例相當有限(至少目前是這樣)。大多數早期採用者說WeakSet可以用來標記對象而無需修改它們。 ES6-Features.org有一個從WeakSet添加和刪除元素的示例,以便跟踪對像是否已被標記:
const planetsOrderFromSun = new Set(); planetsOrderFromSun.add('Mercury'); planetsOrderFromSun.add('Venus').add('Earth').add('Mars'); // 可链式方法 console.log(planetsOrderFromSun.has('Earth')); // True planetsOrderFromSun.delete('Mars'); console.log(planetsOrderFromSun.has('Mars')); // False for (const x of planetsOrderFromSun) { console.log(x); // 输入和输出顺序相同 - Mercury Venus Earth } console.log(planetsOrderFromSun.size); // 3 planetsOrderFromSun.add('Venus'); // 尝试添加重复项 console.log(planetsOrderFromSun.size); // 仍然是3,没有添加重复项 planetsOrderFromSun.clear(); console.log(planetsOrderFromSun.size); // 0
Map所有事物?記錄與ES6集合
Map和Set是鍵值對的漂亮的新ES6集合。也就是說,JavaScript對象仍然可以在許多情況下用作集合。除非情況需要,否則無需切換到新的ES6集合。
MDN有一個很好的問題列表,用於確定何時使用對像或鍵控集合:
- 鍵通常直到運行時才知道嗎?您需要動態查找它們嗎?
- 所有值都具有相同的類型,並且可以互換使用嗎?
- 您是否需要不是字符串的鍵?
- 經常添加或刪除鍵值對嗎?
- 您是否有任意數量(易於更改)的鍵值對?
- 集合是否被迭代?
新的ES6集合產生更易用的JavaScript
JavaScript集合以前非常有限,但這已通過ES6得到糾正。這些新的ES6集合將增強語言的強大功能和靈活性,並簡化採用它們的JavaScript開發人員的任務。
本文是來自Microsoft技術佈道者和DevelopIntelligence關於實用JavaScript學習、開源項目和互操作性最佳實踐(包括Microsoft Edge瀏覽器和新的EdgeHTML渲染引擎)的Web開發系列的一部分。 DevelopIntelligence通過appendTo(其專注於前端的博客和課程網站)提供JavaScript培訓和React培訓課程。
我們鼓勵您在包括Microsoft Edge(Windows 10的默認瀏覽器)在內的各種瀏覽器和設備上進行測試,可以使用dev.microsoftedge.com上的免費工具,包括EdgeHTML問題跟踪器,您可以在其中報告或搜索EdgeHTML問題,例如網站渲染或標準合規性問題。此外,請訪問Edge博客,以獲取來自Microsoft開發人員和專家的最新信息。
關於ES6集合的常見問題解答 (FAQ):Map、Set、WeakMap、WeakSet
JavaScript ES6中Map和WeakMap的主要區別是什麼?
在JavaScript ES6中,Map和WeakMap都用於存儲鍵值對。但是,它們之間存在一些顯著差異。首先,在Map中,鍵可以是任何類型,而在WeakMap中,鍵必須是對象。其次,Map具有size屬性,允許您檢查鍵值對的數量,但WeakMap沒有此屬性。最後,Map對鍵對象持有強引用,這意味著只要Map存在,它們就沒有資格進行垃圾回收。另一方面,WeakMap對鍵對象持有弱引用,這意味著如果對對像沒有其他引用,則可以對其進行垃圾回收。
如何在JavaScript ES6中迭代WeakMap或WeakSet?
與Map和Set不同,WeakMap和WeakSet沒有迭代其元素的方法。這是因為它們旨在對它們的鍵(WeakMap)或值(WeakSet)持有弱引用,這意味著這些可以在任何時間進行垃圾回收。因此,無法保證在嘗試迭代元素時元素仍然存在。如果您需要迭代集合,則應改用Map或Set。
我可以在WeakMap或WeakSet中使用原始數據類型作為鍵嗎?
不可以,您不能在WeakMap或WeakSet中使用原始數據類型作為鍵。這些集合中的鍵必須是對象。這是因為WeakMap和WeakSet對它們的鍵持有弱引用,這意味著如果對它們沒有其他引用,則可以對鍵進行垃圾回收。原始數據類型(例如數字和字符串)不會像對像那樣進行垃圾回收,因此它們不能用作這些集合中的鍵。
為什麼我應該使用WeakMap或WeakSet而不是Map或Set?
WeakMap和WeakSet具有一些獨特的特性,在某些情況下,它們可能比Map或Set更合適。因為它們對它們的鍵(WeakMap)或值(WeakSet)持有弱引用,所以當它們不再使用時,可以對其進行垃圾回收。如果您想將其他數據與對象關聯,但又不想阻止對像在不再需要時進行垃圾回收,這將非常有用。此外,因為WeakMap和WeakSet沒有迭代其元素的方法,所以它們可以為它們存儲的數據提供一定程度的隱私。
當WeakMap或WeakSet中的鍵被垃圾回收時會發生什麼?
當WeakMap或WeakSet中的鍵被垃圾回收時,集合中的相應條目會自動刪除。這是因為這些集合對它們的鍵持有弱引用,這意味著當它們不再使用時,可以對鍵進行垃圾回收。此功能對於管理JavaScript應用程序中的內存非常有用,因為它確保與不再使用的對象關聯的數據也會被清除。
我可以使用WeakMap或WeakSet來存儲臨時數據嗎?
是的,WeakMap和WeakSet非常適合存儲臨時數據。因為它們對它們的鍵(WeakMap)或值(WeakSet)持有弱引用,所以當它們不再使用時,可以對其進行垃圾回收。這意味著當鍵被垃圾回收時,存儲在這些集合中的數據也會被清除。這對於存儲僅在短時間內需要的有用,因為您不必擔心手動清理它。
如何檢查WeakMap或WeakSet是否包含某個鍵或值?
您可以使用has方法來檢查WeakMap或WeakSet是否包含某個鍵。此方法返回一個布爾值,指示該鍵是否存在於集合中。但是,請記住,您不能使用此方法來檢查WeakSet中的某個值,因為此集合中的值是不可訪問的。
我可以從WeakMap或WeakSet中刪除條目嗎?
是的,您可以使用delete方法從WeakMap中刪除條目。此方法刪除與給定鍵關聯的條目,並返回一個布爾值,指示該鍵是否存在於集合中。但是,您不能從WeakSet中刪除條目,因為此集合沒有delete方法。
我可以清除WeakMap或WeakSet中的所有條目嗎?
不可以,您不能清除WeakMap或WeakSet中的所有條目。這些集合沒有clear方法,該方法在Map和Set中可用。這是因為WeakMap和WeakSet旨在在鍵被垃圾回收時自動清理它們的條目。
我可以獲取WeakMap或WeakSet的大小嗎?
不可以,您無法獲取WeakMap或WeakSet的大小。這些集合沒有size屬性,該屬性在Map和Set中可用。這是因為由於垃圾回收,WeakMap或WeakSet的大小可以隨時更改。
以上是ES6集合:使用地圖,設置,弱圖,弱點的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。
