Map
åºçº¿
广æ³å¯ç¨
*
èª 2015å¹´7æ èµ·ï¼æ¤ç¹æ§å·²å¨ä¸»æµæµè§å¨ä¸å¾å°æ¯æï¼å¯å¨å¤§å¤æ°è®¾å¤åæµè§å¨çæ¬ä¸æ£å¸¸ä½¿ç¨ã
* æ¤ç¹æ§çæäºé¨åçæ¯æç¨åº¦å¯è½ææä¸åã
Map 对象ä¿åé®å¼å¯¹ï¼å¹¶ä¸è½å¤è®°ä½é®çåå§æå
¥é¡ºåºãä»»ä½å¼ï¼å¯¹è±¡æè
åå§å¼ï¼é½å¯ä»¥ä½ä¸ºé®æå¼ã
å°è¯ä¸ä¸
const map1 = new Map();
map1.set("a", 1);
map1.set("b", 2);
map1.set("c", 3);
console.log(map1.get("a"));
// Expected output: 1
map1.set("a", 97);
console.log(map1.get("a"));
// Expected output: 97
console.log(map1.size);
// Expected output: 3
map1.delete("b");
console.log(map1.size);
// Expected output: 2
æè¿°
Map 对象æ¯é®å¼å¯¹çéåãMap ä¸çä¸ä¸ªé®åªè½åºç°ä¸æ¬¡ï¼å®å¨ Map çéå䏿¯ç¬ä¸æ äºçãMap 对象æé®å¼å¯¹è¿ä»£ââä¸ä¸ª for...of 循ç¯å¨æ¯æ¬¡è¿ä»£åä¼è¿åä¸ä¸ªå½¢å¼ä¸º [key, value] çæ°ç»ãè¿ä»£ææå
¥é¡ºåºè¿è¡ï¼å³é®å¼å¯¹æ set() æ¹æ³é¦æ¬¡æå
¥å°éåä¸ç顺åºï¼ä¹å°±æ¯è¯´ï¼å½è°ç¨ set() æ¶ï¼map 䏿²¡æå
·æç¸åå¼çé®ï¼è¿è¡è¿ä»£ã
è§èè¦æ± map å®ç°âå¹³åè®¿é®æ¶é´ä¸éåä¸çå ç´ æ°é忬¡çº¿æ§å ³ç³»âãå æ¤ï¼å®å¯ä»¥å¨å é¨è¡¨ç¤ºä¸ºæ£å表ï¼ä½¿ç¨ O(1) æ¥æ¾ï¼ãæç´¢æ ï¼ä½¿ç¨ O(log(N)) æ¥æ¾ï¼æä»»ä½å ¶ä»æ°æ®ç»æï¼åªè¦å¤æåº¦å°äº O(N)ã
é®çç¸ç
é®çæ¯è¾åºäºé¶å¼ç¸çç®æ³ãï¼å®æ¾ç»ä½¿ç¨åå¼ç¸çï¼å° 0 å -0 è§ä¸ºä¸åãæ£æ¥æµè§å¨å
¼å®¹æ§ãï¼è¿æå³ç NaN æ¯ä¸ NaN ç¸ççï¼è½ç¶ NaN !== NaNï¼ï¼å©ä¸ææå
¶ä»ç弿¯æ ¹æ® === è¿ç®ç¬¦çç»æå¤ææ¯å¦ç¸çã
Object å Map çæ¯è¾
Object å Map ç±»ä¼¼çæ¯ï¼å®ä»¬é½å
è®¸ä½ æé®ååä¸ä¸ªå¼ãå é¤é®ãæ£æµä¸ä¸ªé®æ¯å¦ç»å®äºå¼ãå æ¤ï¼å¹¶ä¸ä¹æ²¡æå
¶ä»å
å»ºçæ¿ä»£æ¹å¼äºï¼è¿å»æä»¬ä¸ç´é½æå¯¹è±¡å½æ Map 使ç¨ã
ä¸è¿ Map å Object æä¸äºéè¦çåºå«ï¼å¨ä¸åæ
åµä¸ä½¿ç¨ Map 伿¯æ´å¥½çéæ©ï¼
| Map | Object | |
|---|---|---|
| æå¤çé® |
Map é»è®¤ä¸å
å«ä»»ä½é®ãå®åªå
嫿¾å¼åå
¥çé®å¼å¯¹ã
|
夿³¨ï¼è¿å¯ä»¥éè¿ä½¿ç¨ |
| å®å ¨æ§ |
Map å¯ä»¥å®å
¨å°ä¸ç¨æ·æä¾çé®å¼ä¸èµ·ä½¿ç¨ã
|
å¨ |
| é®çç±»å |
Map çé®å¯ä»¥ä¸ºä»»ä½å¼ï¼å
æ¬å½æ°ã对象æä»»ä½åå§å¼ï¼ã
|
Object çé®å¿
须为 String æ Symbolã
|
| é®çé¡ºåº |
|
尽管ç°å¨æ®éç
è¯¥é¡ºåºæåä»
å¨ ECMAScript 2015 ä¸ä¸ºèªæå±æ§å®ä¹ï¼ECMAScript 2020 è¿å®ä¹äºç»§æ¿å±æ§ç顺åºãä½è¯·æ³¨æï¼æ²¡æå䏿ºå¶å¯ä»¥è¿ä»£å¯¹è±¡çææå±æ§ï¼åç§æºå¶åèªå
å«ä¸åç屿§åéãï¼ |
å¤§å° |
Map ä¸çé¡¹ç®æ°éå¾å®¹æä»å
¶ size 屿§ä¸è·å¾ã
|
ç¡®å® Object ä¸çé¡¹ç®æ°éé常æ´éº»ç¦ï¼æçä¹è¾ä½ãä¸ç§å¸¸è§çæ¹æ³æ¯éè¿è·å Object.keys() è¿åçæ°ç»çé¿åº¦ã
|
| è¿ä»£ |
Map æ¯å¯è¿ä»£å¯¹è±¡ï¼æä»¥å®å¯ä»¥ç´æ¥è¿ä»£ã
|
夿³¨ï¼
|
| æ§è½ |
卿¶åé¢ç¹æ·»å åå é¤é®å¼å¯¹çåºæ¯ä¸è¡¨ç°æ´å¥½ã |
æªé对é¢ç¹æ·»å åå é¤é®å¼å¯¹è¿è¡ä¼åã |
| åºåååè§£æ |
没æå¯¹åºååæè§£æçåçæ¯æã
ï¼ä½ä½ å¯ä»¥éè¿ä½¿ç¨ |
åçæ¯æä½¿ç¨ åçæ¯æä½¿ç¨ |
è®¾ç½®å¯¹è±¡å±æ§
è®¾ç½®å¯¹è±¡å±æ§åæ ·éç¨äº Map 对象ï¼ä½å®¹æé æå°æ°ã
å³ï¼ä»¥ä¸ç代ç è½å¤æ£å¸¸è¿è¡ï¼ä½ä¸æ¨èï¼ï¼
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
ä½è¿ç§è®¾ç½®å±æ§çæ¹å¼ä¸ä¼æ¹å Map çæ°æ®ç»æãå®ä½¿ç¨çæ¯éç¨å¯¹è±¡çç¹æ§ã'bla' ç弿ªè¢«åå¨å¨ Map ä¸ï¼æ æ³è¢«æ¥è¯¢å°ãå
¶ä»ç对è¿ä¸æ°æ®çæä½ä¹ä¼å¤±è´¥ï¼
wrongMap.has("bla"); // false
wrongMap.delete("bla"); // false
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
æ£ç¡®çå卿°æ®å° Map ä¸çæ¹å¼æ¯ä½¿ç¨ set(key, value) æ¹æ³ã
const contacts = new Map();
contacts.set("Jessie", { phone: "213-555-1234", address: "123 N 1st Ave" });
contacts.has("Jessie"); // true
contacts.get("Hilary"); // undefined
contacts.set("Hilary", { phone: "617-555-4321", address: "321 S 2nd St" });
contacts.get("Jessie"); // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete("Raymond"); // false
contacts.delete("Jessie"); // true
console.log(contacts.size); // 1
ç±» Map æµè§å¨ API
æµè§å¨ç±» Map å¯¹è±¡ï¼æç§°ä¸ºâmaplike 对象âï¼æ¯å
¶è¡ä¸ºå¨å¾å¤æ¹é¢é½ç±»ä¼¼äº Map ç Web API æ¥å£ã
å°±å Map 䏿 ·ï¼å¯¹è±¡ä¸çæ¡ç®å¯ä»¥ä»¥æ·»å ç顺åºè¿ä»£ã类似 Map ç对象å Map å
·æç¸åç屿§åæ¹æ³ã使¯ï¼ä¸ Map ä¸åçæ¯ï¼å®ä»¬ä»
å
许æ¯ä¸ªæ¡ç®ä¸çé®åå¼å
·æç¹å®é¢å®ä¹çç±»åã
å
许çç±»åè§èç IDL å®ä¹ç»åºãä¾å¦ï¼RTCStatsReport æ¯ä¸ä¸ªç±»ä¼¼ Map ç对象ï¼å¿
须使ç¨å符串ä½ä¸ºé®ï¼å¯¹è±¡ä½ä¸ºå¼ãè¿æ¯å¨è§è IDL ä¸å®ä¹çï¼
interface RTCStatsReport {
readonly maplike<DOMString, object>;
};
ç±» Map 对象å¯ä»¥æ¯åªè¯»çï¼ä¹å¯ä»¥æ¯å¯åçï¼åè§ä¸é¢ IDL ä¸ç readonly å
³é®åï¼ã
- åªè¯»çç±»
Mapå¯¹è±¡å ·æsize屿§ï¼ä»¥åè¿äºæ¹æ³ï¼entries()ãforEach()ãkeys()ãvalues()å[Symbol.iterator]()ã - å¯åçç±»
Map对象è¿é¢å¤å ·æè¿äºæ¹æ³ï¼clear()ãdelete()åset()ã
é¤äºå¯¹é®åå¼ç±»åçéå¶å¤ï¼å
¶æ¹æ³å屿§çè¡ä¸ºä¸ Map ä¸ç对åºå®ä½ç¸åã
以䏿¯æµè§å¨ä¸åªè¯»çç±» Map 对象ç示ä¾ï¼
æé 彿°
Map()-
å建
Map对象ã
éæå±æ§
Map[Symbol.species]-
ç¨äºå建派ç对象çæé 彿°ã
éææ¹æ³
Map.groupBy()-
æ ¹æ®æä¾çåè°å½æ°è¿åçå¼å°ç»å®çå¯è¿ä»£å¯¹è±¡åç»ãæç»è¿åç
Mapå¯¹è±¡ä½¿ç¨æµè¯å½æ°è¿åçå¯ä¸å¼ä½ä¸ºé®ï¼å¯ç¨äºè·åæ¯ä¸ªç»çå ç´ æ°ç»ã
å®ä¾å±æ§
è¿äºå±æ§å¨ Map.prototype ä¸å®ä¹ï¼å¹¶ç±ææ Map å®ä¾å
±äº«ã
Map.prototype.constructor-
å建å®ä¾å¯¹è±¡çæé 彿°ã对äº
Mapå®ä¾ï¼åå§å¼ä¸ºMapæé 彿°ã Map.prototype.size-
è¿å
Map对象ä¸çé®å¼å¯¹æ°éã Map.prototype[Symbol.toStringTag]-
[Symbol.toStringTag]屿§çåå§å¼æ¯å符串"Map"ãè¯¥å±æ§å¨Object.prototype.toString()ä¸ä½¿ç¨ã
å®ä¾æ¹æ³
Map.prototype.clear()-
ç§»é¤
Mapå¯¹è±¡ä¸ææçé®å¼å¯¹ã Map.prototype.delete()-
ç§»é¤
Mapå¯¹è±¡ä¸æå®çé®å¼å¯¹ï¼å¦æé®å¼å¯¹åå¨å¹¶æå被移é¤ï¼è¿åtrueï¼å¦åè¿åfalseãè°ç¨deleteååè°ç¨map.has(key)å°è¿åfalseã Map.prototype.entries()-
è¿åä¸ä¸ªæ°çè¿ä»£å¨å¯¹è±¡ï¼å ¶å å«
Mapå¯¹è±¡ä¸ææé®å¼å¯¹[key, value]äºå æ°ç»ï¼ä»¥æå ¥é¡ºåºæåã Map.prototype.forEach()-
以æå ¥é¡ºåºä¸º
Map对象ä¸çæ¯ä¸ªé®å¼å¯¹è°ç¨ä¸æ¬¡callbackFnãå¦æä¸ºforEachæä¾äºthisArgåæ°ï¼åå®å°ä½ä¸ºæ¯ä¸æ¬¡ callback çthiså¼ã Map.prototype.get()-
è¿å䏿å®çé®
keyå ³èçå¼ï¼è¥ä¸åå¨å ³èçå¼ï¼åè¿åundefinedã Map.prototype.has()-
è¿åä¸ä¸ªå¸å°å¼ï¼ç¨æ¥è¡¨æ
Mapå¯¹è±¡ä¸æ¯å¦åå¨ä¸æå®çé®keyå ³èçå¼ã Map.prototype.keys()-
è¿åä¸ä¸ªæ°çè¿ä»£å¨å¯¹è±¡ï¼å ¶å å«
Mapå¯¹è±¡ä¸ææå ç´ çé®ï¼ä»¥æå ¥é¡ºåºæåã Map.prototype.set()-
å¨
Map对象ä¸è®¾ç½®ä¸æå®çé®keyå ³èçå¼ï¼å¹¶è¿åMap对象ã Map.prototype.values()-
è¿åä¸ä¸ªæ°çè¿ä»£å¯¹è±¡ï¼å ¶ä¸å å«
Mapå¯¹è±¡ä¸ææçå¼ï¼å¹¶ä»¥æå ¥Map对象çé¡ºåºæåã Map.prototype[Symbol.iterator]()-
è¿åä¸ä¸ªæ°çè¿ä»£å¨å¯¹è±¡ï¼å ¶å å«
Mapå¯¹è±¡ä¸ææå ç´[key, value]äºå æ°ç»ï¼ä»¥æå ¥é¡ºåºæåã
示ä¾
>ä½¿ç¨ Map 对象
const myMap = new Map();
const keyString = "a string";
const keyObj = {};
const keyFunc = function () {};
// æ·»å é®
myMap.set(keyString, "åé®'a string'å
³èçå¼");
myMap.set(keyObj, "åé® keyObj å
³èçå¼");
myMap.set(keyFunc, "åé® keyFunc å
³èçå¼");
console.log(myMap.size); // 3
// 读åå¼
console.log(myMap.get(keyString)); // "åé®'a string'å
³èçå¼"
console.log(myMap.get(keyObj)); // "åé® keyObj å
³èçå¼"
console.log(myMap.get(keyFunc)); // "åé® keyFunc å
³èçå¼"
console.log(myMap.get("a string")); // "åé®'a string'å
³èçå¼"ï¼å 为 keyString === 'a string'
console.log(myMap.get({})); // undefinedï¼å 为 keyObj !== {}
console.log(myMap.get(function () {})); // undefinedï¼å 为 keyFunc !== function () {}
å° NaN ä½ä¸º Map çé®
NaN ä¹å¯ä»¥ä½ä¸ºé®ãè½ç¶ NaN ä¸ä»»ä½å¼çè³ä¸èªå·±é½ä¸ç¸çï¼NaN !== NaN è¿å trueï¼ï¼ä½æ¯å 为ææç NaN çå¼é½æ¯æ æ³åºåçï¼æä»¥ä¸é¢çä¾åæç«ï¼
const myMap = new Map();
myMap.set(NaN, "not a number");
myMap.get(NaN);
// "not a number"
const otherNaN = Number("foo");
myMap.get(otherNaN);
// "not a number"
ä½¿ç¨ for...of è¿ä»£ Map
Map å¯ä»¥ä½¿ç¨ for...of å¾ªç¯æ¥å®ç°è¿ä»£ï¼
const myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (const [key, value] of myMap) {
console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one
for (const key of myMap.keys()) {
console.log(key);
}
// 0
// 1
for (const value of myMap.values()) {
console.log(value);
}
// zero
// one
for (const [key, value] of myMap.entries()) {
console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one
ä½¿ç¨ forEach() è¿ä»£ Map
Map ä¹å¯ä»¥éè¿ forEach() æ¹æ³è¿ä»£ï¼
myMap.forEach((value, key) => {
console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one
Map 䏿°ç»å¯¹è±¡çå ³ç³»
const kvArray = [
["key1", "value1"],
["key2", "value2"],
];
// 使ç¨å¸¸è§ç Map æé 彿°å¯ä»¥å°ä¸ä¸ªäºç»´çé®å¼å¯¹æ°ç»è½¬æ¢æä¸ä¸ª Map 对象
const myMap = new Map(kvArray);
console.log(myMap.get("key1")); // "value1"
// ä½¿ç¨ Array.from 彿°å¯ä»¥å°ä¸ä¸ª Map å¯¹è±¡è½¬æ¢æä¸ä¸ªäºç»´çé®å¼å¯¹æ°ç»
console.log(Array.from(myMap)); // è¾åºå kvArray ç¸åçæ°ç»
// æ´ç®æ´çæ¹æ³æ¥åå¦ä¸åæ ·çäºæ
ï¼ä½¿ç¨å±å¼è¿ç®ç¬¦
console.log([...myMap]);
// æè
å¨é®æè
å¼çè¿ä»£å¨ä¸ä½¿ç¨ Array.fromï¼è¿èå¾å°åªå«æé®æè
å¼çæ°ç»
console.log(Array.from(myMap.keys())); // è¾åº ["key1", "key2"]
å¤å¶æåå¹¶ Maps
Map è½åæ°ç»ä¸æ ·è¢«å¤å¶ï¼
const original = new Map([[1, "one"]]);
const clone = new Map(original);
console.log(clone.get(1)); // one
console.log(original === clone); // false. æµ
æ¯è¾ ä¸ä¸ºåä¸ä¸ªå¯¹è±¡çå¼ç¨
夿³¨ï¼è¯·è®°ä½ï¼æ°æ®æ¬èº«æªè¢«å éã
Map 对象é´å¯ä»¥è¿è¡åå¹¶ï¼ä½æ¯ä¼ä¿æé®çå¯ä¸æ§ã
const first = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);
const second = new Map([
[1, "uno"],
[2, "dos"],
]);
// å并两个 Map 对象æ¶ï¼å¦ææéå¤çé®å¼ï¼ååé¢çä¼è¦çåé¢çã
// å±å¼è¯æ³æ¬è´¨ä¸æ¯å° Map å¯¹è±¡è½¬æ¢ææ°ç»ã
const merged = new Map([...first, ...second]);
console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
Map 对象ä¹è½ä¸æ°ç»åå¹¶ï¼
const first = new Map([
[1, "one"],
[2, "two"],
[3, "three"],
]);
const second = new Map([
[1, "uno"],
[2, "dos"],
]);
// Map å¯¹è±¡åæ°ç»è¿è¡åå¹¶æ¶ï¼å¦ææéå¤çé®å¼ï¼ååé¢çä¼è¦çåé¢çã
const merged = new Map([...first, ...second, [1, "eins"]]);
console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
è§è
| è§è |
|---|
| ECMAScript® 2027 Language Specification> # sec-map-objects> |