1. map和object

MapObject
意外的键Map默认情况不包含任何键,只包含显式插入的键。Object 有一个原型, 原型链上的键名有可能和自己在对象上的设置的键名产生冲突。
键的类型Map的键可以是任意值,包括函数、对象或任意基本类型。Object 的键必须是 String 或是Symbol。
键的顺序Map 中的 key 是有序的。因此,当迭代的时候,Map 对象以插入的顺序返回键值。Object 的键是无序的
sizeMap 的键值对个数可以轻易地通过size 属性获取Object 的键值对个数只能手动计算
迭代Map 是 iterable 的,所以可以直接被迭代。迭代Object需要以某种方式获取它的键然后才能迭代。
性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。

2. map 和 weakMap

(1)Map

map本质上就是键值对的集合,但是普通的Object中的键值对中的键只能是字符串。而ES6提供的Map数据结构类似于对象,但是它的键不限制范围,可以是任意类型,是一种更加完善的Hash结构。如果Map的键是一个原始数据类型,只要两个键严格相同,就视为是同一个键。 实际上Map是一个数组,它的每一个数据也都是一个数组,其形式如下:

const map = [
     ["name","张三"],
     ["age",18],
]

Map数据结构有以下操作方法:

  • **size**map.size 返回Map结构的成员总数。
  • **set(key,value)**:设置键名key对应的键值value,然后返回整个Map结构,如果key已经有值,则键值会被更新,否则就新生成该键。(因为返回的是当前Map对象,所以可以链式调用)
  • **get(key)**:该方法读取key对应的键值,如果找不到key,返回undefined。
  • **has(key)**:该方法返回一个布尔值,表示某个键是否在当前Map对象中。
  • **delete(key)**:该方法删除某个键,返回true,如果删除失败,返回false。
  • **clear()**:map.clear()清除所有成员,没有返回值。

Map结构原生提供是三个遍历器生成函数和一个遍历方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回所有成员的遍历器。
  • forEach():遍历Map的所有成员。
const map = new Map([
     ["foo",1],
     ["bar",2],
])
for(let key of map.keys()){
    console.log(key);  // foo bar
}
for(let value of map.values()){
     console.log(value); // 1 2
}
for(let items of map.entries()){
    console.log(items);  // ["foo",1]  ["bar",2]
}
map.forEach( (value,key,map) => {
     console.log(key,value); // foo 1    bar 2
})

(2)WeakMap

WeakMap 对象也是一组键值对的集合,其中的键是弱引用的。其键必须是对象,原始数据类型不能作为key值,而值可以是任意的。 该对象也有以下几种方法:

  • **set(key,value)**:设置键名key对应的键值value,然后返回整个Map结构,如果key已经有值,则键值会被更新,否则就新生成该键。(因为返回的是当前Map对象,所以可以链式调用)
  • **get(key)**:该方法读取key对应的键值,如果找不到key,返回undefined。
  • **has(key)**:该方法返回一个布尔值,表示某个键是否在当前Map对象中。
  • **delete(key)**:该方法删除某个键,返回true,如果删除失败,返回false。
const wm1 = new WeakMap(),
      wm2 = new WeakMap(),
      wm3 = new WeakMap();
const o1 = {},
      o2 = function() {},
      o3 = window;
wm1.set(o1, 37);
wm1.set(o2, 'azerty');
wm2.set(o1, o2); // value 可以是任意值,包括一个对象或一个函数
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个 WeakMap 对象
wm1.get(o2); // "azerty"
wm2.get(o2); // undefined,wm2 中没有 o2 这个键
wm2.get(o3); // undefined,值就是 undefined
wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (即使值是 undefined)
wm3.set(o1, 37);
wm3.get(o1); // 37
wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false

其clear()方法已经被弃用,所以可以通过创建一个空的WeakMap并替换原对象来实现清除。 实现一个带有clear的weakMap

class ClearableWeakMap {
  constructor(init) {
    this._wm = new WeakMap(init);
  }
  clear() {
    this._wm = new WeakMap();
  }
  delete(k) {
    return this._wm.delete(k);
  }
  get(k) {
    return this._wm.get(k);
  }
  has(k) {
    return this._wm.has(k);
  }
  set(k, v) {
    this._wm.set(k, v);
    return this;
  }
}

WeakMap的设计目的在于,有时想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。一旦不再需要这两个对象,就必须手动删除这个引用,否则垃圾回收机制就不会释放对象占用的内存。 而WeakMap的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用

3. set 和 weakSet

(1)Set

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。 Set有以下操作方法:

  • size:返回 Set 对象中的值的个数
  • add(value):在Set对象尾部添加一个元素。返回该 Set 对象。
  • clear():移除Set对象内的所有元素。
  • delete(value):移除值为 value 的元素,并返回一个布尔值来表示是否移除成功。Set.prototype.has(value) 会在此之后返回 false
  • entries():返回一个新的迭代器对象,该对象包含 Set 对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和 Map 对象保持相似,每个值的键和值相等。
  • foreach((value, key, set) => { /* ... */ ):按照插入顺序,为 Set 对象中的每一个值调用一次 callBackFn。如果提供了thisArg参数,回调中的 this 会是这个参数。
  • keys():与 values() 方法相同,返回一个新的迭代器对象,该对象包含 Set 对象中的按插入顺序排列的所有元素的值。
  • values():返回一个新的迭代器对象,该对象包含 Set 对象中的按插入顺序排列的所有元素的值。
  • has(value):返回一个布尔值,表示该值在 Set 中存在与否。

(2)WeakSet

WeakSet 对象是一些对象值的集合。且其与 Set 类似,WeakSet 中的每个对象值都只能出现一次。在 WeakSet 的集合中,所有对象都是唯一的。 WeakSet和 Set 对象的主要区别有:

  • WeakSet 只能是对象的集合,而不能像 Set 那样,可以是任何类型的任意值。
  • WeakSet 持弱引用:集合中对象的引用为弱引用。如果没有其它的对 WeakSet 中对象的引用,那么这些对象会被当成垃圾回收掉。

持有的方法:

  • add(value):在WeakSet对象尾部添加一个元素。返回该 WeakSet 对象。
  • delete(value):移除值为 value 的元素,并返回一个布尔值来表示是否移除成功。WeakSet.prototype.has(value)会在此之后返回 false
  • has(value):返回一个布尔值,表示该值在 WeakSet 中存在与否。
浙ICP备2021014928号 2023-PRESENT © Eric