目錄
關鍵要點
尋找JavaScript HashMap
缺點#1:ES5中的鍵必須是字符串
缺點#2:對象並非天生可迭代
缺點#3:內置方法衝突的挑戰
使用ES6 Map集合
創建映射並使用常用方法
使用Set集合
弱集合、內存和垃圾回收
WeakMap
使用案例
私有數據用例
DOM節點用例
WeakSet
Map所有事物?記錄與ES6集合
新的ES6集合產生更易用的JavaScript
關於ES6集合的常見問題解答 (FAQ):Map、Set、WeakMap、WeakSet
JavaScript ES6中Map和WeakMap的主要區別是什麼?
如何在JavaScript ES6中迭代WeakMap或WeakSet?
我可以在WeakMap或WeakSet中使用原始數據類型作為鍵嗎?
為什麼我應該使用WeakMap或WeakSet而不是Map或Set?
當WeakMap或WeakSet中的鍵被垃圾回收時會發生什麼?
我可以使用WeakMap或WeakSet來存儲臨時數據嗎?
如何檢查WeakMap或WeakSet是否包含某個鍵或值?
我可以從WeakMap或WeakSet中刪除條目嗎?
我可以清除WeakMap或WeakSet中的所有條目嗎?
我可以獲取WeakMap或WeakSet的大小嗎?
首頁 web前端 js教程 ES6集合:使用地圖,設置,弱圖,弱點

ES6集合:使用地圖,設置,弱圖,弱點

Feb 15, 2025 pm 12:37 PM

ES6 Collections: Using Map, Set, WeakMap, WeakSet

本文探討了四個新的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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1656
14
CakePHP 教程
1415
52
Laravel 教程
1308
25
PHP教程
1256
29
C# 教程
1229
24
神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

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

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

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

JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

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

JavaScript:探索網絡語言的多功能性 JavaScript:探索網絡語言的多功能性 Apr 11, 2025 am 12:01 AM

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

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

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

如何使用Next.js(前端集成)構建多租戶SaaS應用程序 如何使用Next.js(前端集成)構建多租戶SaaS應用程序 Apr 11, 2025 am 08:22 AM

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

從C/C到JavaScript:所有工作方式 從C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

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

如何安裝JavaScript? 如何安裝JavaScript? Apr 05, 2025 am 12:16 AM

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

See all articles