前言
yocto-queue作用
什么是链表?
什么是迭代器&生成器?
生成器
在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。 更具体地说,迭代器是通过使用
next()方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。
链表与数组的区别
源码
yocto-queue框架
class Node {}export default class Queue {#head; // 指向头指针#tail; // 指向当前节点#size; // 当前队列元素个数// 构造函数constructor () {}// 向队列中添加一个值enqueue (value) {}// 删除队列中的下一个值dequeue () {}// 清空队列clear () {}// 清空队列get size () {}*[Symbol.iterator] () {}}
node类
class Node {value; // 当前节点值next; // 指向后一个节点constructor(value) {this.value = value;}}
这里使用到了设计模式中的工厂模式,使用node类实例化出来的对象,都有value和next这两个字段
constructor 构造方法
constructor() {this.clear();}
构造函数只是调用了一下清空队列的方法
这里的clear()方法主要起设置初始值的作用,比如上面虽然定义了size字段,但是并未赋值
clear()方法中有一段this.#size = 0正好可以给size赋初始值,提高代码复用
enqueue
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
dequeue () {const current = this.#head;if (!current) {return;}this.#head = this.#head.next;this.#size--;return current.value;}
clear
clear () {this.#head = undefined;this.#tail = undefined;this.#size = 0;}
size
get size () {return this.#size;}
Symbol.iterator
*[Symbol.iterator] () {let current = this.#head;while (current) {yield current.value;current = current.next;}}
代码作用
这里是为了让实例化出来的对象可以被 for...of 循环
默认情况下,实例化出来的对象是不能循环的,比如这里我们注释掉Symbol.iterator代码部分,打印时浏览器就会提示错误:
export default class Queue {// 其余代码...// *[Symbol.iterator] () {// 内部代码...// }}const queue = new Queue();queue.enqueue('🦄');queue.enqueue('🌈');queue.enqueue('🦄');for (let i of queue) {console.log(i)}// TypeError: queue is not iterableat <anonymous>:78:15
然后我们再取消Symbol.iterator注释,再打印试一下
export default class Queue {// 其余代码...// 取消注释 Symbol.iterator*[Symbol.iterator] () {// 内部代码...}}const queue = new Queue();queue.enqueue('🦄');queue.enqueue('🌈');queue.enqueue('🦄');for (let i of queue) {console.log(i)}// 可以正常打印// 🦄🌈🦄
代码解析
首先函数声明部分是使用了一个简写,这段代码等同于
[Symbol.iterator] = function* () {let current = this.#head;while (current) {yield current.value;current = current.next;}}
