- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
- 这是源码共读的第32期,链接:第32期 | yocto-queue 队列 链表
源码解析
下载到本地后打开
该项目全部目录
在 package.json 中得知 index.js 为索引文件
解读源码
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;
// 如果没有头部 默认肯定为 undefined
} 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 语法糖 设置为可以直接获取的值 返回 当前队列的长度
get size() {
return this.#size;
}
// 设置遍历器并调整为 generate 函数
* [Symbol.iterator]() {
// 把头部设为当前数据
let current = this.#head;
// 只要有数据就一直执行
while (current) {
// 拿到当前数据并把当前的变量改为下一个数据
yield current.value;
current = current.next;
}
}
}
解析半天先解释几个关键词.
- get 关键字
- Symbol.iterator
- generator 函数 (* yield)
get 关键字
get 语法将对象属性绑定到查询该属性时将被调用的函数。
该关键会通过语法糖直接调用 getter 函数 从而在开发者调用是不需要调用函数.
Symbol.iterator
Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。
简单解释就是 可以直接使用 forof 来循环遍历的迭代器 但是内部要迭代的数据和操作可以自定义。
generator 函数
Generator 对象由生成器函数返回并且它符合可迭代协议和迭代器协议。
构造函数
Generator 构造函数并不是全局可用。Generator 的实例必须从生成器函数返回:
function* generator() {
yield 1;
yield 2;
yield 3;
}
const gen = generator(); // "Generator { }"
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
好了 陌生的关键字以及简单了解了使用以及知道是什么了,下面可以调试了。
调试
把下载下来的源码项目先 安装下 包
npm install
在 package.json 找一下测试脚本
在项目目录中找 .test. 或者 test 的文件
找到后可以优先调用下看看工具是否可用
npm run test
ok,接下来可以选择自己写一段 测试方法.
test("test", (t) => {
// 创建队列
const queue = new Queue();
// 检验 入队
queue.enqueue("张三");
queue.enqueue("李四");
// 校验当前队列长度是否一致
t.is(queue.size, 2);
// 校验出队数据是否返回相同 和 功能
t.deepEqual(queue.dequeue(), "张三");
t.is(queue.size, 1);
// 校验迭代器
t.deepEqual([...queue], ["李四"]);
// 校验clear函数
queue.clear();
t.deepEqual(queue.size, 0);
});
测试的调用也是没问题的。
结语
可以阅读他人之长处,阅取他人之他人之精髓,方可进步。