搜尋
首頁web前端js教程淺談JavaScript中的Map、WeakMap、Set和WeakSet

淺談JavaScript中的Map、WeakMap、Set和WeakSet

我猜想,超過70%的JavaScript開發人員只使用物件來收集和維護其專案中的資料。好吧,確實如此,新的集合物件(例如Map和Set)即使在2015年問世也沒有充分利用。

因此,今天,我將討論2015年以來的神奇新功能-MapSetWeakMap#和##WeakSet

在閱讀之前

    這篇文章並不是要告訴你只能用它們。但我見過一些應徵者在編碼考試中使用了其中的一種,我喜歡在某些情況下使用它們。由你決定何時在專案中使用它們。
  • 你應該知道什麼是可迭代的,以便更好地了解我的討論。
Objects

我們應該先討論如何使用物件。

好吧,我相信90%以上的人已經知道這部分內容了,因為你點擊這篇文章是為了了解新的集合對象,但對於JavaScript的初學者來說,我們還是簡單說說它們吧。

const algorithm = { site: "leetcode" };
console.log(algorithm.site); // leetcode

for (const key in algorithm) {
  console.log(key, algorithm[key]);
}

// site leetcode
delete algorithm.site;
console.log(algorithm.site); // undefined

所以我做了一個

algorithm 對象,它的key和value是一個字串類型的值,而我透過用. 關鍵字來呼叫該值。

另外,

for-in 迴圈也很適合在物件中循環。你可以用 [] 關鍵字存取其鍵對應的值。但是不能使用 for-of 循環,因為物件是不可迭代的。

物件的屬性可以用

delete 關鍵字來刪除。這樣就可以徹底擺脫物件的屬性,大家要注意不要跟這種方法混淆。

const algorithm = { site: "leetcode" };
// Property is not removed!!
algorithm.site = undefined;
// Property is removed!!
delete algorithm.site;

algorithm.site = undefined 只是將新值指派給 site

好的,我們已經快速討論了有關物件的一些事項:

    如何新增屬性
  • 如何遍歷物件
  • 如何刪除屬性
Map

Map 是JavaScript中新的集合對象,功能類似於物件。但是,與常規對象相比,存在一些主要差異。

首先,讓我們來看一個建立Map物件的簡單範例。

如何新增屬性

const map = new Map();
// Map(0) {}

Map 不需要建立任何內容,但是新增資料的方式略有不同。

map.set('name', 'john');
// Map(1) {"name" => "john"}

Map 有一個特殊的方法可以在其中新增稱為

set 的屬性。它有兩個參數:鍵是第一個參數,值是第二個參數。

map.set('phone', 'iPhone');
// Map(2) {"name" => "john", "phone" => "iPhone"}
map.set('phone', 'iPhone');
// Map(2) {"name" => "john", "phone" => "iPhone"}

但是,它不允許你在其中新增現有資料。如果 Map 物件中已經存在與新資料的鍵對應的值,則不會新增資料。

map.set('phone', 'Galaxy');
// Map(2) {"name" => "john", "phone" => "Galaxy"}

但是你可以用其他值覆寫現有資料。

如何遍歷物件

Map 是一個可迭代的對象,這表示可以使用

for-of 語句將其對應。

for (const item of map) {
  console.dir(item);
}
// Array(2) ["name", "john"]
// Array(2) ["phone", "Galaxy"]

要記住的一件事是 Map 以數組形式提供數據,你應該解構數組或訪問每個索引以獲取鍵或值。

要只取得鍵或值,還有一些方法可供你使用。

map.keys();
// MapIterator {"name", "phone"}
map.values();
// MapIterator {"john", "Galaxy"}
map.entries();
// MapIterator {"name" => "john", "phone" => "Galaxy"}

你甚至可以使用展開運算元(

...)來取得Map的全部數據,因為展開運算子還可以在幕後與可迭代物件一起運作。

const simpleSpreadedMap = [...map];
// [Array(2), Array(2)]

如何刪除屬性

從 Map 物件中刪除資料也很容易,你所需要做的就是呼叫

delete

map.delete('phone');
// true
map.delete('fake');
// false

delete 傳回布林值,該布林值指示 delete 函數是否成功刪除了資料。如果是,則傳回 true,否則傳回 false

WeakMap

WeakMap起源於Map,因此它們彼此之間非常相似。但是,WeakMap具有很大的不同。

WeakMap的名字是怎麼來的呢?嗯,是因為它與它的引用連結所指向的資料物件的連結或關係沒有Map的連結或關係那麼強,所以它是弱的。

那麼,這到底是什麼意思呢?

差異1:key必須是物件

const John = { name: 'John' };
const weakMap = new WeakMap();
weakMap.set(John, 'student');
// WeakMap {{...} => "student"}
weakMap.set('john', 'student');
// Uncaught TypeError: Invalid value used as weak map key

你可以將任何值作為鍵傳入Map對象,但WeakMap不同,它只接受一個物件作為鍵,否則,它將傳回一個錯誤。

差異2:並非Map中的所有方法都支援

可以使用WeakMap的方法如下。

    delete
  • get
  • has
  • #set
這個主題最大的不同是WeakMap不支援迭代對象的方法。但是為什麼呢?下面將對此進行說明。

區別3:當GC清理引用時,資料會被刪除

與Map相比,這是最大的不同。

let John = { major: "math" };

const map = new Map();
const weakMap = new WeakMap();

map.set(John, 'John');
weakMap.set(John, 'John');

John = null;
/* John 被垃圾收集 */

John 物件被垃圾回收時,Map物件將保持引用鏈接,而WeakMap物件將丟失鏈結。所以當你使用WeakMap時,你應該考慮這個功能。

Set

Set也非常類似Map,但是Set對於單一值更有用。

如何加入屬性

const set = new Set();

set.add(1);
set.add('john');
set.add(BigInt(10));
// Set(4) {1, "john", 10n}

與Map一樣,Set也阻止我們新增相同的值。

set.add(5);
// Set(1) {5}

set.add(5);
// Set(1) {5}

如何遍历对象

由于Set是一个可迭代的对象,因此可以使用 for-offorEach 语句。

for (const val of set) {
  console.dir(val);
}
// 1
// 'John'
// 10n
// 5

set.forEach(val => console.dir(val));
// 1
// 'John'
// 10n
// 5

如何删除属性

这一部分和 Map 的删除完全一样。如果数据被成功删除,它返回 true,否则返回 false

set.delete(5); 
// true

set.delete(function(){});
// false;

如果你不想将相同的值添加到数组表单中,则Set可能会非常有用。

/* With Set */
const set = new Set();
set.add(1);
set.add(2);
set.add(2);
set.add(3);
set.add(3);
// Set {1, 2, 3}

// Converting to Array
const arr = [ ...set ];
// [1, 2, 3]

Object.prototype.toString.call(arr);
// [object Array]

/* Without Set */
const hasSameVal = val => ar.some(v === val);
const ar = [];

if (!hasSameVal(1)) ar.push(1);
if (!hasSameVal(2)) ar.push(2);
if (!hasSameVal(3)) ar.push(3);

WeakSet

与WeakMap一样,WeakSet也将丢失对内部数据的访问链接(如果内部数据已被垃圾收集)。

let John = { major: "math" };

const set = new Set();
const weakSet = new WeakSet();

set.add(John);
// Set {{...}}
weakSet.add(John);
// WeakSet {{...}}

John = null;
/* John 被垃圾收集 */

一旦对象 John 被垃圾回收,WeakSet就无法访问其引用 John 的数据。而且WeakSet不支持 for-offorEach,因为它不可迭代。

比较总结

相同点:添加相同的值不支持。

Map vs. WeakMap:WeakMap仅接受对象作为键,而Map不接受。

Map and Set:

  • 可迭代的对象,支持 for..offorEach... 运算符
  • 脱离GC关系

WeakMap and WeakSet:

  • 不是一个可迭代的对象,不能循环。
  • 如果引用数据被垃圾收集,则无法访问数据。
  • 支持较少的方法。

结语

不过,我想,很多团队或公司还是没有使用Maps或Sets。也许是因为他们觉得没有必要,或者是因为数组仍然可以做到几乎所有他们想要的东西。

然而,在JavaScript中,Maps或Sets可能是非常独特和强大的东西,这取决于每个情况。所以我希望有一天,你能有机会使用它们。

原文地址:https://medium.com/better-programming/map-weakmap-set-weakset-in-javascript-77ecb5161e3

作者:Moon

更多编程相关知识,请访问:编程入门!!

以上是淺談JavaScript中的Map、WeakMap、Set和WeakSet的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

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

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用