js基石之Array,Stack,Queue,Set,WeakSet

98 阅读5分钟

相关文章

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有什么特点

线性结构

Array(数组),Stack(栈),Queue(队列),Set(集合),WeakSet(弱集合)

js中一般使用Array模拟Stack&Queue。

Array vs Stack vs Queue

  1. 访问控制

    • Array:可以直接通过索引访问元素
    • Stack :采用LIFO(后进先出)策略来添加和移除元素。只能从栈顶添加或移除元素。
    • Queue: 采用FIFO(先进先出)策略来添加和移除元素。元素只能从队列的一端添加,而从另一端移除。
  2. 性能

    • Array:在数组的开始或中间位置添加或移除元素可能导致其他元素的索引移动,影响性能。
    • Stack和Queue:添加和移除操作局限于两端,这通常可以有效地执行,除非是实现上的特殊需求导致的性能问题。

Array vs Set

  1. 数据的唯一性

    • 数组:可以包含重复的元素,没有内置机制来保证元素的唯一性。
    • Set :元素唯一,自动去除重复的元素。
  2. 元素的排序

    • 数组:元素有序,可以通过索引来访问。
    • Set :元素无序,不可以通过索引来直接访问。
  3. 访问控制

    • 数组:可以直接通过索引访问元素
    • Set :不能通过索引直接访问元素,但可以通过迭代器或forEach方法遍历元素。
  4. 性能

    • 数组:在数组的开始或中间位置添加或移除元素可能导致其他元素的索引移动,影响性能。
    • Set:增加或删除元素通常具有较高的性能,因为元素的唯一性简化了内部管理。

Set VS WeakSet

  1. 元素类型

    • Set:可以存储任何类型的唯一值,包括原始值和对象引用。
    • WeakSet:仅能存储对象引用,并且这些对象是弱引用,意味着它们不阻止垃圾回收机制回收这些对象。
  2. 可枚举性

    • Set:Set的内容是可枚举的,你可以使用for...of循环、Set.prototype.forEach方法等遍历集合。
    • WeakSet:WeakSet中的对象不可枚举,这意味着没有方法可以获取或清空所有内容,因为没有办法确认集合中的元素是否已经被垃圾回收。
  3. 引用类型

    • Set:对于存储在Set中的对象,Set 对它们的引用是强引用,即它们不会被垃圾回收机制回收,直到被明确移除或Set本身被回收。
    • WeakSet:WeakSet对其元素的引用是弱引用。如果没有其他强引用指向对象,对象可能在任何时间被回收,不管这个对象是否还存在于WeakSet中。
  4. API 方法

    • Set:拥有一整套标准的集合操作方法,如add、delete、has、clear等。
    • WeakSet:方法更少,只具有add、delete和has方法。由于WeakSet是不可枚举的,它没有clear方法。
  5. 使用用途

    • Set:用于存储唯一值的列表,当你需要频繁地检查一个值是否存在于集合中时很有用。
    • WeakSet:更多用于在没有泄漏内存的前提下关联额外的信息到对象上,因为它不会因为WeakSet的引用而阻止对象被回收。
  6. 性能考虑

    • Set:由于它的元素是可枚举的,JavaScript引擎能够优化其性能。
    • WeakSet:由于引擎必须处理弱引用的特殊性质,可以使得在某些情况下的性能不如Set。

WeakSet & WeakMap

相同的目标:设计目的是为了解决在某些场景下的内存管理问题

它们的 "弱" 特性来自于它们对元素或键的弱引用。在这里,弱引用 意味着对象的引用不会阻止它被垃圾回收器回收。这样可以避免内存泄漏,因为只要对象没有其他强引用,在没有任何引用的情况下它们最终会被回收。

相似的存储内容:WeakSet 和 WeakMap 不能存储原始值

原始值(如数字、字符串、布尔值等)与对象不同,原始值不是存储在堆(heap)内存中的对象,它们一般存储在栈(stack)内存上,JS的原始值是通过值自身而非引用来管理的。因此,“弱引用”这个概念并不适用于原始值,它们不是通过引用来操作和访问的。弱引用的机制是为了解决对象的内存管理问题,因为对象的生命周期较难预测而且可能导致内存泄漏。原始值不存在这个问题。