JavaScript数据结构yocto queue队列链表代码分析
本文深入分析JavaScript轻量级队列库yocto-queue的源码实现。通过解析链表结构、入队出队逻辑及Symbol.iterator迭代器定义,展示其相比原生Array.push和shift在大数据量操作下的性能优势。结合VS Code远程开发环境,详细解读核心代码片段,帮助开发者理解高效队列与迭代器的构建细节。
前言
Yocto-queue 是一种专门设计用于高效存储和检索数据的数据结构。它属于队列类型,本质上是一个元素集合,其核心特性在于元素从一端添加,并从另一端移除。
该数据结构专为处理大规模数组数据而设计。当应用场景涉及大量 Array.push 和 Array.shift 操作时,Yocto-queue 能展现出比原生数组更优越的性能表现。
项目仓库地址:sindresorhus/yocto-queue: Tiny queue data structure (github.com)
准备工作
虽然在浏览器中直接调试代码十分便捷,但为了体现开发的专业性,我们推荐使用 Github Workspace 进行本地 VS Code 开发。
首先打开 yocto-queue 仓库,创建一个 Github Codespace。返回 Github 首页,在导航栏点击 Workspace,找到刚创建的项目并选择使用 VS Code 打开,具体操作如图:

VS Code 会提示安装 Github Workspace 插件。该插件功能类似于 Remote SSH,旨在为远程服务器上的开发提供支持。这样做的好处包括跨平台兼容性、多端协同操作以及统一开发环境。
分析代码
源码如下:
/*
How it works:
`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
*/
class Node {
value;
next;
constructor(value) {
this.value = value;
}
}
export default class Queue {
#head;
#tail;
#size;
constructor() {
this.clear();
}
enqueue(value) {
const node = new Node(value);
if (this.#head) {
this.#tail.next = node;
this.#tail = node;
} else {
this.#head = node;
this.#tail = node;
}
this.#size++;
}
dequeue() {
const current = this.#head;
if (!current) {
return;
}
this.#head = this.#head.next;
this.#size--;
return current.value;
}
clear() {
this.#head = undefined;
this.#tail = undefined;
this.#size = 0;
}
get size() {
return this.#size;
}
* [Symbol.iterator]() {
let current = this.#head;
while (current) {
yield current.value;
current = current.next;
}
}
}
队列
队列是一种遵循先进先出(FIFO)原则的数据结构,具备以下核心特点:
- 新元素始终被添加到队列的末尾。
- 队列中已存在的元素保持其原有的先后顺序不变。
- 在任何时刻,只能从队列的起始端(头部)移除元素。
入队
enqueue(value) {
const node = new Node(value);
if (this.#head) {
this.#tail.next = node;
this.#tail = node;
} else {
this.#head = node;
this.#tail = node;
}
this.#size++;
}
该方法用于向队列中添加值,接收一个值作为参数,并据此创建一个新的 Node 对象。
如果队列中已存在 head 和 tail 节点,新节点将被追加到队列末尾。具体操作是将 tail 节点的 next 属性指向新节点,并将 tail 属性更新为新节点。
若队列为空,新节点将同时成为 head 和 tail 节点。最后,队列的 size 属性会增加,以反映新添加节点后的队列大小。
出队
该方法用于从队列中移除顶部节点的值,并将其返回。
dequeue() {
const current = this.#head;
if (!current) {
return;
}
this.#head = this.#head.next;
this.#size--;
return current.value;
}
实现时,首先检查 head 属性是否为空以判断队列状态。若队列为空,方法返回 null;若不为空,则将 head 属性更新为队列中的下一个节点,并减少 size 属性以反映移除操作。最后,返回原 head 节点的值。
迭代器
此功能允许 yocto-queue 在 for...of 循环中被直接使用。
* [Symbol.iterator]() {
let current = this.#head;
while (current) {
yield current.value;
current = current.next;
}
}
通过定义 Symbol.iterator 符号,为队列提供了自定义迭代器。迭代器初始化时将 current 变量设为队列的 head 属性。随后进入循环,只要 current 不为 null 便持续执行。每次迭代中,使用 yield 关键字输出 current 节点的 value 属性,并将 current 更新为下一个节点。这使得 for...of 循环能够遍历队列中的所有值。
总结
通过阅读 yocto-queue 的源码,我们掌握了队列的具体实现方式以及迭代器的应用技巧。对比数组与队列两种数据结构的使用场景:数组在查询方面速度较快,但插入操作较慢;而队列则在插入操作上更快,但查询速度相对较慢。
以上就是JavaScript数据结构yocto queue队列链表代码分析的详细内容,更多关于JavaScript yocto queue队列链表的资料请关注本站其它相关文章!
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
