js基石之Object,Map,WeakMap

115 阅读4分钟

相关文章

js基石之数据类型一:类型分类&区别
js基石之数据类型二:类型判断
js基石之数据类型三:类型转换
js基石之Number:本质
js基石之Number:应用(数字运算,数字&字符串转换,不同进制表示&相互转换)
js基石之字符: ASCII,GBK,Unicode,utf-32,utf-16,utf-8,encodeuri,encodeuricomponent,base64
js基石之Symbol值
js基石之Object,Map,WeakMap
js基石之Array,Stack,Queue,Set,WeakSet

先有问题再有答案

  1. js中常见的键值对结构有哪些
  2. js中有常见的线性结构有哪些
  3. Map vs Object 有哪些区别
  4. Map vs WeakMap 有哪些区别
  5. Array vs Stack vs Queue 有哪些区别
  6. Array vs Set 有哪些区别
  7. WeakSet & WeakMap有什么特点

键值对结构

Object,Map(映射),WeakMap(弱映射)。

Map vs Object 

  1. 键的类型:

    • Object 的键仅限于字符串或符号(Symbol),尽管现代 JavaScript 引擎可以通过隐式转换接受其他类型的键,但最终这些键都会被转换成字符串或符号。
    • Map 允许任意类型的值作为键,包括对象、基本类型或其他 Map。
  2. 迭代顺序:

    • 在 Map 中,元素保持插入的顺序进行迭代。这就意味着当你迭代 Map 时,键值对会按照它们被添加进 Map 的顺序来返回。
    • 对于 Object,直到 ES2015(ES6)之前,属性的迭代顺序并未明确定义,然而,现代 JavaScript 引擎对于非数值键以添加的顺序进行迭代,数值键(或看起来像数值的键)会被按照数值大小排序后迭代。因此,Object 的属性顺序并不像 Map 那样严格或清晰。
  3. 性能:

    • 在频繁添加和删除键值对的场景下,Map 拥有更优的性能。Map 是为了频繁的增删键值对操作而优化的。
    • Object 则在处理少量键值对的场景下通常表现良好,但它并不专门为频繁的键值对的增加和删除而设计。
  4. 内置方法和属性:

    • Map 拥有内置的方法,如 map.size(直接提供成员数量),以及 map.set、map.get、map.has 和 map.delete 等操作方法。
    • 而 Object 必须依赖外部函数或方法,如 Object.keys 或 Object.entries 等,来获取属性列表或大小,且增删改查操作在语法上不如 Map 直接。
  5. 序列化:

    • Map 不能直接使用 JSON.stringify 进行序列化,需要先转换为兼容格式(如数组)。
    • Object 自然支持序列化为 JSON,这使得在需要持久化或网络传输数据时,Object 可能更直接方便。

Map vs WeakMap

  1. 键的类型:

    • Map 可以使用任意类型的值(包括对象、原始值)作为键。
    • WeakMap 的键必须是对象,不能是原始值(如数字、字符串、布尔值等)。
  2. 引用的强度:

    • Map 中的键对于它的值是强引用。这意味着只要 Map 存在,键值对就会一直存在,除非显式删除。
    • WeakMap 中键是弱引用的,而值并不是。一旦没有其他引用指向键对象,这个对象就可以被垃圾回收机制回收(即使它还是一个 WeakMap 的键)。
    let weakmap = new WeakMap();
    let obj = {};   // 创建一个普通对象
    let value = {}; // 创建另一个普通对象用作值
    weakmap.set(obj, value); 
    //`obj` 设置为 `weakmap` 的键,`value` 作为它的值 
    // 此时,只要 `obj` 存活,`weakmap` 就包含 `obj``value` 的映射 
    // 但 `weakmap``obj` 是弱引用,不会阻止 `obj` 被垃圾回收 
    // 如果现在没有其他引用指向 `value` 
    // 一旦 `obj` 被回收,`weakmap` 中的键值对也会消失,`value` 也可能被垃圾回收(如果没有其他引用指向它)
  1. 可迭代性:

    • Map 是可迭代的,它拥有 forEach 方法和 Iterator 接口,可以使用 for...of 循环迭代。
    • WeakMap 不可迭代,没有提供遍历其键值对的方法,因为其键弱引用的特性意味着随时可能发生变化(对象可能被垃圾回收)。
  2. 方法集合:

    • Map 提供了大量的方法操作键值对,如 set、get、delete、has、clear 以及可以获取大小的 size 属性等。
    • WeakMap 只有 set、get、delete 和 has 四个方法,没有 clear 方法,也没有提供获取集合大小的方法,因为键是弱引用,随时可能会变。
  3. 应用场景:

    • Map 一般用于需要明确地存储和迭代键值对的场合。
    • WeakMap 适用于不希望键长期存在或不想通过键对值产生强引用的场合,常用于内部实现,缓存和存储跟键对象相关联的私有数据,而且不影响键对象的垃圾回收。
  4. 内存管理:

    • 在 Map 的使用中,只要 Map 本身不被回收,它所引用的键值对也不会被回收。
    • WeakMap 则可以帮助开发者在不影响垃圾回收的情况下更好地管理内存,通过使用 WeakMap,开发者能够避免可能导致内存泄漏的强键引用。