ES6的Map類型

本文內容html

  • Map的基本使用
  • Map支持的數據類型
  • Map的迭代
  • Map與其餘對象的轉化

在Map出現以前,要實現相似需求,只能使用Object,可是Object仍是存在一些問題的。編程

  • 若是使用Object做爲key存儲在{}中,key最終是當作[object Object]來使用的
  • Object的keys是無序的
  • 沒法安全遍歷Object
  • 沒法直接獲取Object大小
Map 對象保存鍵值對。任何值(對象或者原始值) 均可以做爲一個鍵或一個值。

基本操做

new Map([iterator])
  • iterator <Iterator> 能夠是一個數組或者其餘iterator對象,其元素爲鍵值對(如['key', 'value'])。
  • null或undefined不會生效,返回一個空的Map
  • 非iterator會拋出錯誤 TypeError: object is not iterable
const map = new Map();
// Create
map.set('name','xialei');
map.set('site', 'https://www.ddhigh.com');
// Update
map.set('name', 'xialeistudio');
// Read
map.get('name');
// Delete
map.delete('name');
// 清空
map.clear();
// map大小
console.log(map.size);

數據類型測試

JS中基本數據類型有string、number、boolean、null、undefined、symbol,複雜數據類型有object(包括object,array,function等),還有個特殊的NaN(typeof結果是number),分別對這些類型進行測試segmentfault

const map = new Map();
const sKey = 'key',
    nKey = 1,
    bKey = true,
    nullKey = null,
    uKey = undefined,
    symbolKey = Symbol("key"),
    oKey = {},
    ooKey = oKey,
    aKey = [],
    fKey = function () { },
    nanKey = NaN;

map.set(sKey, "string")
    .set(nKey, "number")
    .set(bKey, "boolean")
    .set(nullKey, "null")
    .set(uKey, "undefined")
    .set(symbolKey, "symbol")
    .set(oKey, "object")
    .set(aKey, "array")
    .set(fKey, "function")
    .set(nanKey, "NaN");

console.log(map);
console.log(map.get(sKey) === "string", map.get("key") === "string");
console.log(map.get(nKey) === "number", map.get(1) === "number");
console.log(map.get(bKey) === "boolean", map.get(true) === "boolean");
console.log(map.get(nullKey) === "null", map.get(null) === "null");
console.log(map.get(uKey) === "undefined", map.get(undefined) === "undefined");
console.log(map.get(symbolKey) === "symbol");
console.log(map.get(oKey) === "object", map.get({}) === "object", map.get(oKey) === map.get(ooKey));
console.log(map.get(aKey) === "array", map.get([]) === "array");
console.log(map.get(fKey) === "function", map.get(function () { }) === "function");
console.log(map.get(nanKey) === "NaN", map.get(NaN) === "NaN");

輸出以下數組

Map {
  'key' => 'string',
  1 => 'number',
  true => 'boolean',
  null => 'null',
  undefined => 'undefined',
  Symbol(key) => 'symbol',
  {} => 'object',
  [] => 'array',
  [Function: fKey] => 'function',
  NaN => 'NaN'
}
true true
true true
true true
true true
true true
true
true false true
true false
true false
true true

結論安全

  • string/number/boolean/null/undefined/NaN 按值存儲,值一致便可訪問
  • symbol必須是同一個Symbol才能訪問,詳見深刻淺出ES6的Symbol類型
  • object/array/function等Object類型按照引用訪問,必須是同一個引用才能夠訪問
  • Map是有序的,按照插入順序
  • Map.set方法支持鏈式操做

Map的迭代

for...of

同時迭代鍵值編程語言

// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const [k, v] of map) {
    console.log(k, v);
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const [k, v] of map.entries()) {
    console.log(k, v);
}

迭代鍵函數

// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const k of map.keys()) {
    console.log(k, map.get(k));
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const [k] of map.entries()) { // 解構賦值
    console.log(k, map.get(k));
}

迭代值測試

// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const v of map.values()) {
    console.log(v);
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);

for (const [,v] of map.entries()) {
    console.log(v);
}

forEach()this

forEach方法的順序是value, key,不是key, value!
const map = new Map();
map.set("1", 1);
map.set("2", 2);

map.forEach((value, key) => {
    console.log(value, key);
});

Map與其餘類型的轉換

Map與Object

const obj = {
    name: 'xialei',
    site: 'https://www.ddhigh.com'
};
const map = new Map(obj);
console.log(map);

執行報錯TypeError: object is not iterable,由於Object不是可迭代對象。spa

可迭代對象:ES6新出的語法,對象或對象的原型鏈實現了Symbol.iterator方法,關於迭代器的內容將在下一篇文章中詳細介紹

咱們給Object.prototype添加屬性方法來支持迭代:

warning: 正式代碼請謹慎修改原型鏈!
const obj = {
    name: 'xialei',
    site: 'https://www.ddhigh.com'
};

Object.prototype[Symbol.iterator] = function () { // Symbol.iterator能夠理解爲全局惟一的標識
    const keys = Object.keys(this);
    let keyIndex = 0;

    return {
        next() {
            if (keyIndex < keys.length) {
                const key = keys[keyIndex++];
                return { value: [key, obj[key]] }; // 迭代值
            }
            return { done: true }; // 迭代結束
        }
    }
};

const map = new Map(obj);
console.log(map);

Map與數組

只支持[[key, value]]這種二維數組。二維數組的每個元素包含key和value兩個子元素
const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);

Map與Map

因爲Map是可迭代對象,所以能夠做爲參數傳給Map構造函數

兩個Map的元素是同樣的,不是Map不相等,由於不是同一個對象

const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);
const map2 = new Map(map);

console.log(map === map2); // false

Map的合併

多個Map能夠合併,相同key會被覆蓋,規則爲後面的覆蓋前面的
const map = new Map([
    [1, 1],
    [2, 2]
]);
const map2 = new Map([
    [1, 2]
]);

const map3 = new Map([...map, ...map2]);
console.log(map3); // Map { 1 => 2, 2 => 2 }

總結

Map的出現解決了傳統object沒法直接解決的問題,更好地向標準編程語言靠近(標準編程語言通常會提供Map集合),使用的坑也比較少(好比沒有object做爲key時轉換爲[object Object]的問題)。

0.jpeg
更多原創文章,盡在天天進步一點點

相關文章
相關標籤/搜索