【JavaScript】JS——Map data type
What is Map?
An object that stores key-value pairs.
- Ability to remember the original insertion order of keys
- Any value (object or primitive) can be used as a key or value.
characteristic
A key in Map can only appear once, and the new value will overwrite the old value.
Iteration method: for...of loop, returns an array of [key,value]
.
Equality of keys: comparison based on zero value equality
NaN === NaN
-0 === +0
Comparison between Map and Object
- Map does not contain any keys by default. It only contains the displayed key-value pairs.
object
There is a prototype
let map1 = new Map()
let obj1 = new Object()
console.log(map1);
console.log(obj1);
-
Safety:
Map
is an independent data structure and there is no object prototype. Setting a user-supplied key-value pair onObject
could allow an attacker to overwrite the object's prototype, which could lead to potential security issues:- Prototype chain pollution: The attacker pollutes the object's prototype chain by providing specific key-value pairs. For example, an attacker can modify or hijack methods and properties on an object's prototype by setting the
__proto__
attribute to modify the object's prototype. - Function hijacking: If the value in the key-value pair provided by the user is a function, and the function is directly assigned to the object's properties, the attacker may hijack the object's properties by providing a malicious function.
- Object overriding: If a key in a user-supplied key-value pair conflicts with a property in the object's prototype, an attacker may be able to override the object's prototype properties by supplying a specific key-value pair.
- Access restriction bypass
const victim = { }; const attacker = { evilMethod: () => console.log('恶意方法被调用') }; victim.__proto__ = attacker; // 调用原型上的恶意方法 victim.evilMethod(); // 恶意方法被调用
- Prototype chain pollution: The attacker pollutes the object's prototype chain by providing specific key-value pairs. For example, an attacker can modify or hijack methods and properties on an object's prototype by setting the
-
Key type:
Map
's key can be any value (function, object, or any primitive value),Object
's key must beString
orSymbol
-
The key is a function instance: cache function call results
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('从缓存中获取结果'); 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)); // 输出:从缓存中获取结果,5
-
-
Order of keys:
Map
The object iterates over the entries, keys, and values in the order in which they were inserted. -
Size: The number of items in
Map
, obtained using thesize
attribute. Object is usually returned by gettingObject.keys()
Array length. -
Iteration: Map is an iterable object,
Object
does not implement the iteration protocol, and iteration cannot be implemented by defaultfor ...of
-
Performance: Scenarios involving frequent addition and deletion of key-value pairs perform better
-
Serialization or parsing:
Map
No native support for serialization or parsing;Object
Serialization supported usingJSON。stringify()
Object to JSON, useJSON.parse()
to parse JSON into Object
Creation of map
- grammar
new Map()
new Map(iterable)
iterable
An element is an array or other iterable of key-value pairs.
const map1 = new Map()
const map2 = new Map([
[1, "a"],
[2, "b"],
[3, "c"],
[4, "c"]
])
console.log(map1,map2);
map properties
size()
map2.size // 4
map related methods
get()
get(key)
Get the specified element in this map
console.log(map2.get(1)); // a
set()
set(key, value)
adds or updates a specified key-value pair to the Map
object
map1.set("a", 1)
map1.set("a", 3)
map1.set("b", 2)
// 链式添加 键值对
map1.set("bar","foo").set(1, "foobar")
console.log(map1);
has()
Returns a Boolean value indicating whether the element with the specified key exists.
delete()
delete(key)
Removes the element with the specified key from this map.
console.log(map1.delete("a")); // true 删除成功返回true
clear()
Remove all elements in this map.
map1.clear()
console.log(map1); // Map(0) {size: 0}
groupBy()
Map.groupBy(items, callbackFn)
Each element of the Map object executes the provided callback function and is grouped according to the value returned by the callback function.
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 traversal
forEach()
forEach(callbackFn)
Execute the provided function once for each key/value pair in this map, in insertion order.
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()
Returns a new iterable iterator object containing all key-value pairs in the Map object in order of insertion.
const mapIter = map2.entries()
console.log(mapIter.next().value);
console.log(mapIter.next().value);
console.log(mapIter.next().value);
keys() | values()
Returns an iterator object, the keys() method returns the key of each element in the Map object, and the values() method returns the value of each element in the Map object.
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);