什么是Map?
存儲鍵值對的對象。
- 能夠記住鍵的原始插入順序
- 任何值(對象或原始值)都可以作為鍵或值。
特性
Map中的一個鍵只能出現(xiàn)一次,新的值會覆蓋舊的值。
迭代方式:for…of循環(huán),返回一個 [key,value]
的數(shù)組。
鍵的相等:基于零值相等比較
NaN === NaN
-0 === +0
Map與Object的比較
- Map默認(rèn)不包含任何鍵。它只包含顯示存入的鍵值對。
object
有原型
let map1 = new Map()
let obj1 = new Object()
console.log(map1);
console.log(obj1);
-
安全性:
Map
是一種獨立的數(shù)據(jù)結(jié)構(gòu),不存在對象原型。而在Object
上設(shè)置用戶提供的鍵值對可能會允許攻擊者覆蓋對象的原型,這可能會引發(fā)潛在的安全問題:- 原型鏈污染:攻擊者通過提供特定的鍵值對,污染對象的原型鏈。例如,攻擊者可以通過設(shè)置
__proto__
屬性來修改對象的原型,從而修改或劫持對象的原型上的方法和屬性。 - 函數(shù)劫持:如果用戶提供的鍵值對中的值是一個函數(shù),并且該函數(shù)被直接賦值給對象的屬性,攻擊者可能會通過提供惡意的函數(shù)來劫持對象的屬性。
- 對象重寫:如果用戶提供的鍵值對中的鍵與對象的原型中的屬性沖突,攻擊者可能通過提供特定的鍵值對來覆蓋對象的原型屬性。
- 訪問限制繞過
const victim = {}; const attacker = { evilMethod: () => console.log('惡意方法被調(diào)用') }; victim.__proto__ = attacker; // 調(diào)用原型上的惡意方法 victim.evilMethod(); // 惡意方法被調(diào)用
- 原型鏈污染:攻擊者通過提供特定的鍵值對,污染對象的原型鏈。例如,攻擊者可以通過設(shè)置
-
鍵的類型:
Map
的鍵可以為任何值(函數(shù)、對象或任何原始值),Object
的鍵必須為String
或Symbol
-
鍵為函數(shù)實例:緩存函數(shù)調(diào)用結(jié)果
const cache = new Map(); function createCacheKey(fn, ...args) { return `${fn.name}(${args.join(',')})`; } function calculateResult(x, y) { const cacheKey = createCacheKey(calculateResult, x, y); if (cache.has(cacheKey)) { console.log('從緩存中獲取結(jié)果'); return cache.get(cacheKey); } const result = x + y; cache.set(cacheKey, result); return result; } console.log(calculateResult(2, 3)); // 輸出:5 console.log(calculateResult(2, 3)); // 輸出:從緩存中獲取結(jié)果,5
-
-
鍵的順序:
Map
對象按照插入的順序迭代條目、鍵和值。 -
大?。?code>Map中的項目數(shù)量,使用
size
屬性獲知,Object通常是通過獲取Object.keys()
返回的數(shù)組長度。 -
迭代:Map 是可迭代對象,
Object
沒有實現(xiàn)迭代協(xié)議,默認(rèn)不能通過for ...of
實現(xiàn)迭代 -
性能:涉及頻繁添加和刪除鍵值對的場景表現(xiàn)更好
-
序列化或解析:
Map
沒有序列化或解析的原生支持;Object
支持使用JSON。stringify()
序列化Object到JSON,使用JSON.parse()
解析JSON為Object
map的創(chuàng)建
- 語法
new Map()
new Map(iterable)
iterable
一個元素是鍵值對的數(shù)組或其他可迭代對象。
const map1 = new Map()
const map2 = new Map([
[1, "a"],
[2, "b"],
[3, "c"],
[4, "c"]
])
console.log(map1,map2);
map的屬性
size()
map2.size // 4
map相關(guān)方法
get()
get(key)
獲取該 map 中的指定元素
console.log(map2.get(1)); // a
set()
set(key, value)
向 Map
對象添加或更新一個指定的鍵值對
map1.set("a", 1)
map1.set("a", 3)
map1.set("b", 2)
// 鏈?zhǔn)教砑?鍵值對
map1.set("bar","foo").set(1, "foobar")
console.log(map1);
has()
返回一個布爾值,指示具有指定鍵的元素是否存在.
delete()
delete(key)
從該 map 中刪除指定鍵的元素。
console.log(map1.delete("a")); // true 刪除成功返回true
clear()
移除該 map 中的所有元素.
map1.clear()
console.log(map1); // Map(0) {size: 0}
groupBy()
Map.groupBy(items, callbackFn)
Map對象每個元素都執(zhí)行提供的回調(diào)函數(shù),根據(jù)回調(diào)函數(shù)返回的值進(jìn)行分組
const inventory = [
{ name: 'Tom', age: 9 },
{ name: 'Bob', age: 5 },
{ name: 'Alice', age: 23 },
{ name: 'Taixi', age: 12 },
];
const result = Map.groupBy(inventory, ({ age }) =>
age < 18 ? "teenager" : "young",
);
console.log(result.get("teenager"));
map的遍歷
forEach()
forEach(callbackFn)
按插入順序?qū)υ?map 中的每個鍵/值對執(zhí)行一次提供的函數(shù)。
const map2 = new Map([
[1, "a"],
[2, "b"],
[3, "c"],
[4, "c"]
])
function logMapElement(value, key, map) {
console.log(`m[${key}]=${value}=${map.get(key)}`);
}
map2.forEach(logMapElement)
entries()
按照插入順序,返回一個新的可迭代迭代器對象,包含了Map對象中的所有鍵值對。
const mapIter = map2.entries()
console.log(mapIter.next().value);
console.log(mapIter.next().value);
console.log(mapIter.next().value);
keys() | values()
返回一個迭代器對象,keys()方法返回Map對象中每個元素的鍵,values()方法返回Map對象中每個元素的值。文章來源:http://www.zghlxwxcb.cn/news/detail-757025.html
const mapIter1 = map2.keys()
console.log(mapIter1.next().value);
console.log(mapIter1.next().value);
console.log(mapIter1.next().value);
const mapIter2 = map2.values()
console.log(mapIter2.next().value);
console.log(mapIter2.next().value);
console.log(mapIter2.next().value);
文章來源地址http://www.zghlxwxcb.cn/news/detail-757025.html
到了這里,關(guān)于【JavaScript】JS——Map數(shù)據(jù)類型的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!