首頁 >web前端 >前端問答 >es6 map成員是唯一的麼

es6 map成員是唯一的麼

青灯夜游
青灯夜游原創
2022-10-31 18:43:521721瀏覽

es6 map成員是唯一的。 ES6新增的Map資料結構類似對象,key值不限於字串,成員值唯一;Map結構提供了「值—值」的對應,是一種更完善的Hash結構實作。 Map物件保存鍵值對,並且能夠記住鍵的原始插入順序;任何值(物件或原始值)都可以作為一個鍵或一個值。

es6 map成員是唯一的麼

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

Map和Set都是ES6新增的資料結構

  • Map 類似對象,key值不限於字串,成員值唯一。

  • Set 類似數組,成員值唯一。

Map 基本概念

ES6 提供了 Map 資料結構。它類似於對象,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種類型的值(包括對象)都可以當作鍵。也就是說,Object 結構提供了「字串—值」的對應,Map 結構提供了「值—值」的對應,是一種更完善的 Hash 結構實作。如果你需要「鍵值對」的資料結構,Map 比 Object 更適合。

Map 特徵

  • Map 物件保存鍵值對,並且能夠記住鍵的原始插入順序。

  • 任何值(物件或原始值) 都可以當作一個鍵或一個值。

  • Map 是 ES6 中引入的新的資料結構,可以參考 ES6 Map 與 Set

Maps 和Objects 的差異

  • #一個Object 的鍵只能是字串或Symbols,但一個Map的鍵可以是任意值。

  • Map 中的鍵值是有序的(FIFO 原則),而新增到物件中的鍵則不是。

    關於物件是無序的官方解釋: 1.An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method. 2.Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版規範。因此,使用 for-in 語句遍歷物件屬性時遍歷書序並非屬性建構順序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是較老的 ECMA-262 第三版規範,屬性遍歷順序由屬性建構的順序決定。

  • Map 的鍵值對個數可以從 size 屬性取得,而 Object 的鍵值則只能手動計算。

  • Object 都有自己的原型,原型鏈上的鍵名有可能和你自己在物件上的設定的鍵名產生衝突。

Map 屬性

  • #Map.prototype.size – 傳回Map 物件鍵/值對的數量。

Map 操作方法

  • #Map.prototype.clear() – 移除Map 物件的所有鍵/值對。
  • Map.prototype.set() – 設定鍵值對,傳回該 Map 物件。
  • Map.prototype.get() – 傳回鍵對應的值,如果不存在,則傳回 undefined。
  • Map.prototype.has() – 傳回布林值,用於判斷 Map 中是否包含鍵對應的值。
  • Map.prototype.delete() – 刪除 Map 中的元素,刪除成功回傳 true,失敗回傳 false。

Map 迴圈方法

Map 的遍歷順序就是插入順序。

  • Map.prototype.keys():傳回鍵名的遍歷器。
  • Map.prototype.values():傳回鍵值的遍歷器。
  • Map.prototype.entries():傳回所有成員的遍歷器。
  • Map.prototype.forEach():遍歷 Map 的所有成員。

其他方法

  • for of 由於有iterable 所以也可以使用此方法

開始建立

使用Map 類型和new 關鍵字來建立Map:

不只是數組,任何具有Iterator 介面、且每個成員都是一個雙元素的陣列的資料結構 所以Set Map 陣列都可以建立Map

建立空map 再加

let map1 = new Map();
map1.set('123',123)

陣列建立Map

const m2 = new Map([['baz', 3]]);

#set 建立Map

const set = new Set([
  ['foo', 1],
  ['bar', 2]
]);

const m3 = new Map(set);

map 建立新的map

#注意m3 === m2 //false

const m3 = new Map(m2);

#範例:可以做什麼

和物件最大的差別: 多型別的key

#

字符串

var myMap = new Map(); 
var keyString = "a string"; 
myMap.set(keyString, "和键'a string'关联的值");

对象

var myMap = new Map(); 
var keyObj = {}
myMap.set(keyObj, "和键 keyObj 关联的值");

函数

var myMap = new Map(); 
var keyFunc = function () {} // 函数 
myMap.set(keyFunc, "和键 keyFunc 关联的值");

NaN

var myMap = new Map(); 
myMap.set(NaN, "not a number");

Map 遍历成员方法

keys() , values() , entries()Map 的遍历顺序就是插入顺序

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"

for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}

使用扩展运算符可以快速转数组

const map = new Map([  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

[...map.keys()]
// [1, 2, 3]

[...map.values()]
// ['one', 'two', 'three']

[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]

[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]

转为数组后,可以使用数组的map,filter方法

const map0 = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');

const map1 = new Map(
  [...map0].filter(([k, v]) => k < 3)
);
// 产生 Map 结构 {1 => &#39;a&#39;, 2 => &#39;b&#39;}

const map2 = new Map(
  [...map0].map(([k, v]) => [k * 2, &#39;_&#39; + v])
    );
// 产生 Map 结构 {2 => &#39;_a&#39;, 4 => &#39;_b&#39;, 6 => &#39;_c&#39;}

Map 增 删 查 清空

const m = new Map();
const o = {p: &#39;Hello World&#39;};

m.set(o, &#39;content&#39;)
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false
m.clear()

与其他数据结构的互相转换

(1)Map 转为数组

前面已经提过,Map 转为数组最方便的方法,就是使用扩展运算符(...)。

const myMap = new Map()
  .set(true, 7)
  .set({foo: 3}, [&#39;abc&#39;]);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ &#39;abc&#39; ] ] ]

var outArray = Array.from(myMap);

(2)数组 转为 Map

将数组传入 Map 构造函数,就可以转为 Map。

new Map([
  [true, 7],
  [{foo: 3}, [&#39;abc&#39;]]
])
// Map {
//   true => 7,
//   Object {foo: 3} => [&#39;abc&#39;]
// }

(3)Map 转为对象

如果所有 Map 的键都是字符串,它可以无损地转为对象。

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

const myMap = new Map()
  .set(&#39;yes&#39;, true)
  .set(&#39;no&#39;, false);
strMapToObj(myMap)
// { yes: true, no: false }

如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。

(4)对象转为 Map

对象转为 Map 可以通过Object.entries()

let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));

此外,也可以自己实现一个转换函数。

function objToStrMap(obj) {
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}

(5)Map 转为 JSON

Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。

function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set(&#39;yes&#39;, true).set(&#39;no&#39;, false);
strMapToJson(myMap)
// &#39;{"yes":true,"no":false}&#39;

另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON。

function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({foo: 3}, [&#39;abc&#39;]);
mapToArrayJson(myMap)
// &#39;[[true,7],[{"foo":3},["abc"]]]&#39;

(6)JSON 转为 Map

JSON 转为 Map,正常情况下,所有键名都是字符串。

function jsonToStrMap(jsonStr) {
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap(&#39;{"yes": true, "no": false}&#39;)
// Map {&#39;yes&#39; => true, &#39;no&#39; => false}

但是,有一种特殊情况,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。

function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

jsonToMap(&#39;[[true,7],[{"foo":3},["abc"]]]&#39;)
// Map {true => 7, Object {foo: 3} => [&#39;abc&#39;]}

其他

Map 的合并

var first = new Map([[1, &#39;one&#39;], [2, &#39;two&#39;], [3, &#39;three&#39;],]); 
var second = new Map([[1, &#39;uno&#39;], [2, &#39;dos&#39;]]); // 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的,对应值即 uno,dos, three 
var merged = new Map([...first, ...second]);

Map 的克隆

var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]); 
var myMap2 = new Map(myMap1); 
console.log(original === clone); // 打印 false。 Map 对象构造函数生成实例,迭代出新的对象。

注意事项

注意,只有对同一个对象的引用,Map 结构才将其视为同一个键。这一点要非常小心。

const map = new Map();

map.set([&#39;a&#39;], 555);
map.get([&#39;a&#39;]) // undefined

虽然NaN不严格相等于自身,但 Map 将其视为同一个键。

let map = new Map();
map.set(NaN, 123);
map.get(NaN) // 123

【相关推荐:javascript视频教程编程视频

以上是es6 map成員是唯一的麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn