【JS】ES6新范例Map与Set

打印 上一主题 下一主题

主题 896|帖子 896|积分 2688

一、Map

Map 对象保存键值对,并且能够记住键的原始插入序次。任何值(对象或者原始值)都可以作为键或值。
形貌

Map 对象是键值对的聚集。Map 中的一个键只能出现一次;它在 Map 的聚集中是独一无二的。
Map 对象按键值对迭代——一个 for…of 循环在每次迭代后会返回一个形式为 [key, value] 的数组。迭代按插入序次进行,即键值对按 set() 方法初次插入到聚集中的序次(也就是说,当调用 set() 时,map 中没有具有相同值的键)进行迭代。
键是怎样对比相等

键的比力基于零值相等算法。(它曾经使用同值相等,将 0 和 -0 视为差别。)这意味着 NaN 是与 NaN 相等的(虽然 NaN !== NaN),剩下所有其他的值是根据 === 运算符的效果判定是否相等。
根本使用

实例属性:size(Map长度)
实例方法:


  • 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.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 [Symbol.iterator] () 返回一个新的迭代器对象,其包含 Map 对象中所有元素 [key, value] 二元数组,以插入序次排列。
  1. const myMap = new Map();
  2. const keyString = "a string";
  3. const keyObj = {};
  4. const keyFunc = function () {};
  5. // 添加键
  6. myMap.set(keyString, "和键'a string'关联的值");
  7. myMap.set(keyObj, "和键 keyObj 关联的值");
  8. myMap.set(keyFunc, "和键 keyFunc 关联的值");
  9. console.log(myMap.size); // 3
  10. // 读取值
  11. console.log(myMap.get(keyString)); // "和键'a string'关联的值"
  12. console.log(myMap.get(keyObj)); // "和键 keyObj 关联的值"
  13. console.log(myMap.get(keyFunc)); // "和键 keyFunc 关联的值"
  14. console.log(myMap.get("a string")); // "和键'a string'关联的值",因为 keyString === 'a string'
  15. console.log(myMap.get({})); // undefined,因为 keyObj !== {}
  16. console.log(myMap.get(function () {})); // undefined,因为 keyFunc !== function () {}
复制代码
可迭代

  1. const myMap = new Map();
  2. myMap.set(0, "zero");
  3. myMap.set(1, "one");
  4. for (const [key, value] of myMap) {
  5.   console.log(`${key} = ${value}`);
  6. }
  7. // 0 = zero
  8. // 1 = one
  9. for (const key of myMap.keys()) {
  10.   console.log(key);
  11. }
  12. // 0
  13. // 1
  14. for (const value of myMap.values()) {
  15.   console.log(value);
  16. }
  17. // zero
  18. // one
  19. for (const [key, value] of myMap.entries()) {
  20.   console.log(`${key} = ${value}`);
  21. }
  22. // 0 = zero
  23. // 1 = one
复制代码
Map与数组

  1. const kvArray = [
  2.   ["key1", "value1"],
  3.   ["key2", "value2"],
  4. ];
  5. // 使用常规的 Map 构造函数可以将一个二维的键值对数组转换成一个 Map 对象
  6. const myMap = new Map(kvArray);
  7. console.log(myMap.get("key1")); // "value1"
  8. // 使用 Array.from 函数可以将一个 Map 对象转换成一个二维的键值对数组
  9. console.log(Array.from(myMap)); // 输出和 kvArray 相同的数组
  10. // 更简洁的方法来做如上同样的事情,使用展开运算符
  11. console.log([...myMap]);
  12. // 或者在键或者值的迭代器上使用 Array.from,进而得到只含有键或者值的数组
  13. console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]
复制代码
复制Map

  1. const original = new Map([[1, "one"]]);
  2. const clone = new Map(original);
  3. console.log(clone.get(1)); // one
  4. console.log(original === clone); // false. 浅比较 不为同一个对象的引用
复制代码
合并Map

Map 对象间可以进行合并,但是会保持键的唯一性。背面的会覆盖前面的。
  1. const first = new Map([
  2.   [1, "one"],
  3.   [2, "two"],
  4.   [3, "three"],
  5. ]);
  6. const second = new Map([
  7.   [1, "uno"],
  8.   [2, "dos"],
  9. ]);
  10. // 合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的。
  11. // 展开语法本质上是将 Map 对象转换成数组。
  12. const merged = new Map([...first, ...second]);
  13. console.log(merged.get(1)); // uno
  14. console.log(merged.get(2)); // dos
  15. console.log(merged.get(3)); // three
复制代码
Map与数组合并

  1. const first = new Map([
  2.   [1, "one"],
  3.   [2, "two"],
  4.   [3, "three"],
  5. ]);
  6. const second = new Map([
  7.   [1, "uno"],
  8.   [2, "dos"],
  9. ]);
  10. // Map 对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
  11. const merged = new Map([...first, ...second, [1, "eins"]]);
  12. console.log(merged.get(1)); // eins
  13. console.log(merged.get(2)); // dos
  14. console.log(merged.get(3)); // three
复制代码
与Object对比

MapObject键默认不包含任何键,只包含显示存入的键值对。键可以为任何值(包罗函数、对象以及任何原始范例)Object有原型,所以包含默认的键。键范例必须为StringSymbol巨细size属性获取Object.keys().length迭代可迭代没有迭代协议,不能通过for…of迭代性能在涉及频仍添加和删除键值对的场景中体现更好未针对频仍添加和删除键值对进行优化 二、Set

Set 对象存储任何范例(无论是原始值还是对象引用)的唯一值。
形貌

Set 对象是值的合集(collection)。聚集(set)中的元素只会出现一次,即聚集中的元素是唯一的。你可以按照插入序次迭代聚集中的元素。插入序次对应于 add() 方法成功将每一个元素插入到聚集中(即,调用 add() 方法时聚集中不存在相同的元素)的序次。
怎样对比值的相等

值的相等是基于零值相等算法的。(曾使用会将 0 和 -0 视为差别值的同值算法。拜见浏览器兼容性。)这意味着 NaN 和 undefined 会被视为是相同的值(纵然 NaN !== NaN),而所有其他的值则基于 === 运算符的语义进行相等比力。
性能

has 方法查抄某个值是否在聚集中,其采用的方式的均匀时间比逐个测试先前添加到聚集中的元素更快。特别是当一个数组的长度(length)等于聚集的巨细(size)时,这比 Array.prototype.includes 方法的均匀速度更快。
根本使用

实例属性:size(Map长度)
实例方法:


  • Set.prototype.add(): 在 Set 对象中插入一个新的具有指定值的元素。
  • Set.prototype.clear(): 从 Set 对象中移除所有元素。
  • Set.prototype.delete():移除与 value 关联的元素,并返回一个布尔值来表示是否移除成功。Set.prototype.has(value) 会在此之后返回 false。
  • Set.prototype.entries():返回一个新的迭代器对象,该对象包含 Set 对象中的代表每个元素的 [value, value] 数组。这与 Map 对象类似,因此 Set 的每个条目的 key 和 value 都相同。
  • Set.prototype.forEach():按照值插入的序次为 Set 对象中的每个值调用一次 callbackFn。如果提供了 thisArg 参数,它将被用作每次调用 callbackFn 时的 this 值。
  • Set.prototype.has():返回一个布尔值,表示给定值在 Set 对象中是否存在。
  • Set.prototype.keys():Set.prototype.values() 的别名。
  • Set.prototype.values():返回一个新的迭代器对象,该对象按插入序次天生 Set 对象中每个元素的值。
  • Set.prototype [Symbol.iterator] ():返回一个新的迭代器对象,该对象按插入序次天生 Set 对象中每个元素的值。
  1. const mySet1 = new Set();
  2. mySet1.add(1); // Set(1) { 1 }
  3. mySet1.add(5); // Set(2) { 1, 5 }
  4. mySet1.add(5); // Set(2) { 1, 5 }
  5. mySet1.add("some text"); // Set(3) { 1, 5, 'some text' }
  6. const o = { a: 1, b: 2 };
  7. mySet1.add(o);
  8. mySet1.add({ a: 1, b: 2 }); // o 是不同对象的引用,所以这是可以的
  9. mySet1.has(1); // true
  10. mySet1.has(3); // false,因为并未将 3 添加到集合中
  11. mySet1.has(5); // true
  12. mySet1.has(Math.sqrt(25)); // true
  13. mySet1.has("Some Text".toLowerCase()); // true
  14. mySet1.has(o); // true
  15. mySet1.size; // 5
  16. mySet1.delete(5); // 从集合中移除 5
  17. mySet1.has(5); // false,5 已从集合中移除
  18. mySet1.size; // 4,因为我们刚刚移除了一个值
  19. mySet1.add(5); // Set(5) { 1, 'some text', {...}, {...}, 5 }——先前删除的元素会作为新的元素被添加,不会保留删除前的原始位置
  20. console.log(mySet1); // Set(5) { 1, "some text", {…}, {…}, 5 }
复制代码
与数组的关系

  1. const myArray = ["value1", "value2", "value3"];
  2. // 使用常规的 Set 构造函数将 Array 转换为 Set
  3. const mySet = new Set(myArray);
  4. mySet.has("value1"); // 返回 true
  5. // 使用展开语法将 Set 转换为 Array。
  6. console.log([...mySet]); // 将显示与 myArray 完全相同的数组
复制代码
数组去重

  1. // 用于从数组中删除重复元素
  2. const numbers = [2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5];
  3. console.log([...new Set(numbers)]); // [2, 3, 4, 5, 6, 7, 32]
复制代码
零值相等算法

原本js中,NaN !== NaN,但是零值相等算法视为相等,-0 与 0也视作相等。
  1. const set = new Set([NaN, NaN]);
  2. console.log(set); // Set(1) {NaN}
  3. const set1 = new Set([0, -0]);
  4. console.log(set1); // Set(1) {0}
复制代码
与Array对比

SetArray值允许存储重复的值不允许存储重复的值。如果尝试向 Set 添加一个已经存在的值,该值将被忽略。元素的范例判定使用严格相等(===)判定元素是否相等使用零值相等算法,类似于严格相等(===),但 NaN 被视为等于 NaN,-0 === 0。性能在添加、删除和查找元素时具有更高的性能,特别是对于大量数据。处理大量数据不如Set 使用场景

Array:适用于必要存储有序且大概包含重复元素的数据的场景,如列表、队列、栈等。
Set:适用于必要存储唯一值的聚集,如在必要查抄是否包含某个值或必要快速去重时。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

乌市泽哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表