From bcce6d10dadaec9dc4f3a5e451edf1e4ba4a1ec9 Mon Sep 17 00:00:00 2001 From: yangzhen <3104844212@qq.com> Date: Tue, 17 Dec 2024 15:04:25 +0800 Subject: [PATCH 1/2] 1 --- node_modules/end-of-stream/index.js | 93 +++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/node_modules/end-of-stream/index.js b/node_modules/end-of-stream/index.js index c77f0d5..d3163a3 100644 --- a/node_modules/end-of-stream/index.js +++ b/node_modules/end-of-stream/index.js @@ -1,80 +1,150 @@ +// 引入 `once` 模块,`once` 函数通常用于确保一个回调函数只会被调用一次, +// 在后续代码中可能用于避免多次触发相同的回调逻辑,保证事件处理的唯一性。 var once = require('once'); +// 定义一个空函数 `noop`,它不执行任何实际操作,在代码中可能作为默认的回调占位符使用, +// 当需要一个空的函数回调,但又不想传入 `null` 或 `undefined` 时可以用它。 var noop = function() {}; +// 定义一个函数 `isRequest`,用于判断传入的 `stream` 参数是否代表一个请求相关的流对象。 +// 判断依据是流对象是否具有 `setHeader` 方法并且 `abort` 属性是一个函数, +// 通常符合这种特征的流对象可能是与 HTTP 请求等相关的可操作流。 var isRequest = function(stream) { return stream.setHeader && typeof stream.abort === 'function'; }; +// 定义一个函数 `isChildProcess`,用于判断传入的 `stream` 参数是否代表一个子进程相关的流对象。 +// 判断条件是流对象具有 `stdio` 属性,且 `stdio` 是一个长度为3的数组, +// 这符合 Node.js 中子进程标准输入、输出、错误流的一种常见表示形式。 var isChildProcess = function(stream) { - return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3; }; +// 定义 `eos` 函数,它主要用于处理流(`stream`)的结束相关逻辑,比如流在可读、可写结束, +// 或者出现错误、关闭等情况时执行相应的回调函数,并提供了取消监听等相关功能。 var eos = function(stream, opts, callback) { + // 如果传入的 `opts` 参数是一个函数,说明可能只传入了回调函数而省略了 `opts` 对象, + // 则将当前的 `opts` 当作 `null`,并把传入的函数当作回调函数重新调用 `eos` 函数进行处理。 if (typeof opts === 'function') return eos(stream, null, opts); + // 如果没有传入 `opts` 参数,则初始化它为空对象,确保后续使用时有默认值可参考。 if (!opts) opts = {}; + // 使用 `once` 函数包装传入的回调函数(如果没有传入回调函数,则使用之前定义的 `noop` 空函数作为默认), + // 保证回调函数只会被执行一次,避免重复触发带来的问题。 callback = once(callback || noop); + // 获取流对象的可写状态对象,通常包含了流可写相关的一些属性,比如缓冲区状态等, + // 后续可根据这个状态对象判断流的可写情况以及进行相关逻辑处理。 var ws = stream._writableState; + // 获取流对象的可读状态对象,类似地,它包含了流可读相关的属性,如已读取的数据量、是否结束等信息, + // 用于判断流的可读状态及后续逻辑处理。 var rs = stream._readableState; - var readable = opts.readable || (opts.readable !== false && stream.readable); - var writable = opts.writable || (opts.writable !== false && stream.writable); - var cancelled = false; - + // 根据传入的 `opts.readable` 属性或者流本身的可读属性(如果 `opts.readable` 未明确设置为 `false`)来确定 `readable` 的值, + // 表示流是否处于可读状态,用于后续判断流结束等相关逻辑。 + var readable = opts.readable || (opts.readable!== false && stream.readable); + // 按照类似的规则确定 `writable` 的值,即根据 `opts.writable` 属性或者流本身的可写属性(若 `opts.writable` 未设为 `false`)来判断流是否可写, + // 用于后续相关逻辑判断。 + var writable = opts.writable || (opts.writable!== false && stream.writable); + // 定义一个变量 `cancelled`,用于标记是否取消了相关的事件监听,初始值为 `false`, + // 后续在取消操作时会将其设置为 `true`。 + + // 定义 `onlegacyfinish` 函数,它作为一个事件处理回调函数,用于处理旧版本流(`legacy streams`)的 `end` 或 `close` 事件。 + // 如果流已经不可写了,就调用 `onfinish` 函数,进行后续的结束相关处理。 var onlegacyfinish = function() { if (!stream.writable) onfinish(); }; + // 定义 `onfinish` 函数,用于处理流可写部分结束的情况。 + // 首先将 `writable` 设置为 `false`,表示可写状态结束,然后如果流已经不可读了,就调用传入的 `callback` 回调函数, + // 传递 `stream` 作为 `this` 上下文,触发相应的业务逻辑(比如通知外部流的可写部分已完成等)。 var onfinish = function() { writable = false; if (!readable) callback.call(stream); }; + // 定义 `onend` 函数,用于处理流可读部分结束的情况。 + // 将 `readable` 设置为 `false`,表示可读状态结束,接着如果流已经不可写了,就调用 `callback` 回调函数, + // 同样传递 `stream` 作为 `this` 上下文,执行相应的逻辑(例如通知外部流的可读部分已完成等)。 var onend = function() { readable = false; if (!writable) callback.call(stream); }; + // 定义 `onexit` 函数,用于处理子进程流(通过 `isChildProcess` 判断)退出的情况。 + // 根据子进程的退出码(`exitCode`)来决定回调函数 `callback` 的参数,如果退出码存在(表示有错误), + // 则传入一个带有错误信息的 `Error` 对象作为回调函数的参数,否则传入 `null`,以此来通知外部子进程的退出状态。 var onexit = function(exitCode) { - callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + callback.call(stream, exitCode? new Error('exited with error code: ' + exitCode) : null); }; + // 定义 `onerror` 函数,用于处理流发生错误的情况,直接将错误对象 `err` 作为参数传递给 `callback` 回调函数, + // 使得外部可以知晓流出现了错误并进行相应的处理(比如记录日志、进行错误提示等)。 var onerror = function(err) { callback.call(stream, err); }; + // 定义 `onclose` 函数,用于处理流关闭的情况。 + // 它会在下一个事件循环(`process.nextTick`)中调用 `onclosenexttick` 函数,这样做可以确保一些异步操作的顺序和时机控制, + // 避免在关闭事件触发时立即执行可能还未准备好的逻辑。 var onclose = function() { process.nextTick(onclosenexttick); }; + // 定义 `onclosenexttick` 函数,用于在流关闭后的下一个事件循环中进行更细致的判断和处理。 + // 如果已经取消了相关操作(`cancelled` 为 `true`),则直接返回,不进行后续处理。 + // 如果流处于可读状态且可读状态对象存在,并且可读状态不是正常结束(`rs.ended` 为 `false` 或者 `rs.destroyed` 为 `true`), + // 则调用 `callback` 回调函数并传入一个表示过早关闭的 `Error` 对象,提示外部流关闭不符合预期(可读部分还未正常结束)。 + // 同理,如果流处于可写状态且可写状态对象存在,并且可写状态不是正常结束(`ws.ended` 为 `false` 或者 `ws.destroyed` 为 `true`), + // 也调用 `callback` 回调函数并传入相应的错误对象,提示可写部分过早关闭。 var onclosenexttick = function() { if (cancelled) return; - if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close')); - if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close')); + if (readable &&!(rs && (rs.ended &&!rs.destroyed))) return callback.call(stream, new Error('premature close')); + if (writable &&!(ws && (ws.ended &&!ws.destroyed))) return callback.call(stream, new Error('premature close')); }; + // 定义 `onrequest` 函数,用于在请求相关流(通过 `isRequest` 判断)的请求对象(`stream.req`)上监听 `finish` 事件, + // 当请求完成时调用 `onfinish` 函数进行后续处理。 var onrequest = function() { stream.req.on('finish', onfinish); }; + // 根据流对象的类型进行不同的事件监听设置。 + // 如果流对象是请求相关的流(通过 `isRequest` 判断为真),则进行以下事件监听: + // 监听 `complete` 事件,当请求完成时调用 `onfinish` 函数; + // 监听 `abort` 事件,当请求被中止时调用 `onclose` 函数; + // 如果流对象有请求对象(`stream.req`),则调用 `onrequest` 函数进行 `finish` 事件监听, + // 否则监听 `request` 事件,当有请求时调用 `onrequest` 函数进行后续处理。 if (isRequest(stream)) { stream.on('complete', onfinish); stream.on('abort', onclose); if (stream.req) onrequest(); else stream.on('request', onrequest); - } else if (writable && !ws) { // legacy streams + } else if (writable &&!ws) { // legacy streams + // 如果流对象是旧版本的可写流(可写但没有可写状态对象,通过 `writable &&!ws` 判断), + // 则监听 `end` 和 `close` 事件,当这些事件触发时调用 `onlegacyfinish` 函数进行处理。 stream.on('end', onlegacyfinish); stream.on('close', onlegacyfinish); } + // 如果流对象是子进程相关的流(通过 `isChildProcess` 判断为真),则监听 `exit` 事件, + // 当子进程退出时调用 `onexit` 函数进行相应的处理,通知外部子进程的退出状态。 if (isChildProcess(stream)) stream.on('exit', onexit); + // 无论流对象属于哪种类型,都统一监听以下一些通用的事件: + // 监听 `end` 事件,当可读部分结束时调用 `onend` 函数进行处理; + // 监听 `finish` 事件,当可写部分结束时调用 `onfinish` 函数进行处理; + // 如果 `opts.error` 没有明确设置为 `false`(默认情况下),则监听 `error` 事件, + // 当流出现错误时调用 `onerror` 函数传递错误信息给回调函数; + // 监听 `close` 事件,当流关闭时调用 `onclose` 函数进行后续处理。 stream.on('end', onend); stream.on('finish', onfinish); - if (opts.error !== false) stream.on('error', onerror); + if (opts.error!== false) stream.on('error', onerror); stream.on('close', onclose); + // 返回一个函数,这个函数用于取消之前对各种事件的监听操作。 + // 当调用这个返回的函数时,会将 `cancelled` 标记设置为 `true`,表示已取消监听, + // 然后依次移除之前添加的各个事件监听器,避免后续不必要的事件触发和逻辑执行, + // 比如移除对 `complete`、`abort`、`request`、`finish`、`exit`、`end`、`error`、`close` 等事件的监听器。 return function() { cancelled = true; stream.removeListener('complete', onfinish); @@ -91,4 +161,5 @@ var eos = function(stream, opts, callback) { }; }; -module.exports = eos; +// 将 `eos` 函数作为模块的导出内容,使得其他模块可以通过引入该模块来使用 `eos` 函数处理流的结束相关逻辑。 +module.exports = eos; \ No newline at end of file -- 2.34.1 From 3a1527323ce57de947e473a114e08e97268a3912 Mon Sep 17 00:00:00 2001 From: yangzhen <3104844212@qq.com> Date: Tue, 17 Dec 2024 15:12:58 +0800 Subject: [PATCH 2/2] 11 --- node_modules/es6-iterator/index.js | 94 +++++++- public/create-vote.html | 375 ++++++++++++++++------------- 2 files changed, 296 insertions(+), 173 deletions(-) diff --git a/node_modules/es6-iterator/index.js b/node_modules/es6-iterator/index.js index 790475f..45720fa 100644 --- a/node_modules/es6-iterator/index.js +++ b/node_modules/es6-iterator/index.js @@ -1,57 +1,110 @@ +// 启用严格模式,在严格模式下,JavaScript 代码会遵循更严格的语法和行为规范,有助于发现更多潜在的错误并提升代码质量。 "use strict"; +// 引入 `es5-ext/array/#/clear` 模块,可能用于清空数组相关操作,从模块路径推测它与扩展的数组功能相关。 +// 这里将引入的模块赋值给 `clear` 变量,以便后续在代码中使用对应的功能。 var clear = require("es5-ext/array/#/clear") - , assign = require("es5-ext/object/assign") - , callable = require("es5-ext/object/valid-callable") - , value = require("es5-ext/object/valid-value") - , d = require("d") - , autoBind = require("d/auto-bind") - , Symbol = require("es6-symbol"); + // 引入 `es5-ext/object/assign` 模块,通常用于将多个对象的属性合并到一个目标对象上,类似 `Object.assign` 的功能, + // 但可能是经过扩展或具有特定兼容性处理的版本,赋值给 `assign` 变量供后续使用。 + , assign = require("es5-ext/object/assign") + // 引入 `es5-ext/object/valid-callable` 模块,可能用于验证某个值是否为可调用的(比如函数),保障后续代码中对可调用对象的使用安全, + // 并将其赋值给 `callable` 变量。 + , callable = require("es5-ext/object/valid-callable") + // 引入 `es5-ext/object/valid-value` 模块,大概是用于验证某个值是否符合特定的有效性要求,具体取决于该模块内部实现, + // 赋值为 `value` 变量供代码中进行值的有效性判断使用。 + , value = require("es5-ext/object/valid-value") + // 引入 `d` 模块,从代码使用情况看,它可能是一个用于创建具有特定属性描述符的对象属性的工具函数(类似 `Object.defineProperty` 的简化或扩展用法), + // 具体功能需看其内部实现细节,赋值给 `d` 变量以便后续使用。 + , d = require("d") + // 引入 `d/auto-bind` 模块,推测是用于自动绑定函数上下文(比如将函数的 `this` 指向特定对象)的功能模块, + // 赋值给 `autoBind` 变量用于后续相关操作。 + , autoBind = require("d/auto-bind") + // 引入 `es6-symbol` 模块,用于在 JavaScript 中支持 `Symbol` 类型,`Symbol` 常用于创建唯一的、不可变的标识符, + // 在这里用于定义一些特殊的属性键等情况,赋值给 `Symbol` 变量供代码使用。 + , Symbol = require("es6-symbol"); +// 获取 `Object.defineProperty` 和 `Object.defineProperties` 方法的引用,分别用于定义单个对象属性和多个对象属性, +// 后续会使用它们来创建具有特定行为和属性描述符的对象属性,确保对象属性的正确设置和访问控制等。 var defineProperty = Object.defineProperty, defineProperties = Object.defineProperties, Iterator; +// 将 `Iterator` 函数作为模块的导出内容,同时在当前模块内也使用 `Iterator` 变量来指代这个函数, +// 该函数用于创建一个迭代器对象,用于遍历某个列表(`list`)并处理相关的更新操作(如添加、删除、清空元素等情况)。 module.exports = Iterator = function (list, context) { + // 检查是否使用 `new` 关键字来调用 `Iterator` 构造函数,如果不是,则抛出一个 `TypeError` 异常, + // 这是遵循构造函数的常规使用规范,确保对象实例化的正确方式。 if (!(this instanceof Iterator)) throw new TypeError("Constructor requires 'new'"); + // 使用 `Object.defineProperties` 方法为当前实例(`this`)定义三个属性:`__list__`、`__context__` 和 `__nextIndex__`。 + // 通过 `d` 函数(具体功能由其模块实现决定)来设置属性的描述符,使其具有特定的可写性(`"w"` 表示可写)等特征。 + // `__list__` 属性存储传入的要迭代的列表数据(通过 `value` 函数验证其有效性后赋值), + // `__context__` 属性存储传入的上下文对象(如果有的话),`__nextIndex__` 属性初始化为 `0`,用于记录迭代的位置索引。 defineProperties(this, { __list__: d("w", value(list)), __context__: d("w", context), __nextIndex__: d("w", 0) }); + // 如果没有传入上下文对象(`context` 为 `null` 或 `undefined`),则直接返回,不进行后续与上下文相关的操作(比如监听上下文事件等)。 if (!context) return; + // 使用 `callable` 函数验证上下文对象的 `on` 方法是否是可调用的(即是否为函数),确保后续可以安全地进行事件监听绑定操作。 callable(context.on); + // 在上下文对象上监听 `_add` 事件,当该事件触发时,调用当前迭代器实例的 `_onAdd` 方法进行处理, + // 这样迭代器可以根据列表元素添加的情况更新自身的迭代状态等信息。 context.on("_add", this._onAdd); + // 类似地,监听 `_delete` 事件,触发时调用 `_onDelete` 方法,用于处理列表元素删除时迭代器的相应调整。 context.on("_delete", this._onDelete); + // 监听 `_clear` 事件,触发时调用 `_onClear` 方法,以应对列表被清空的情况对迭代器状态进行处理。 context.on("_clear", this._onClear); }; -// Internal %IteratorPrototype% doesn't expose its constructor +// 删除 `Iterator` 函数原型对象上的 `constructor` 属性,这样在使用迭代器实例时,不会默认暴露其构造函数引用, +// 可能是出于封装或避免不必要的外部访问构造函数的考虑。 delete Iterator.prototype.constructor; +// 使用 `Object.defineProperties` 方法为 `Iterator` 函数的原型对象(`Iterator.prototype`)定义多个属性和方法, +// 通过 `assign` 函数将多个属性描述对象合并后进行定义,实现了迭代器的核心功能以及相关的辅助方法。 defineProperties( Iterator.prototype, assign( { + // `_next` 方法是迭代器内部用于获取下一个元素索引的私有方法(以下划线开头通常表示私有方法,虽然 JavaScript 并没有真正的私有方法概念,但这是一种约定)。 + // 它的逻辑如下: + // 如果 `__list__` 属性不存在(可能表示列表已经被清空或者未正确初始化等情况),则返回 `undefined`,表示迭代结束。 + // 如果存在 `__redo__` 属性(这个属性可能用于记录需要重新处理的索引情况,具体看其使用场景),则从 `__redo__` 数组中取出第一个元素作为索引 `i`, + // 如果取出的元素不为 `undefined`,则返回该索引值,表示下一个要处理的元素索引;否则继续后续判断。 + // 如果当前的 `__nextIndex__` 小于列表的长度(即还有未迭代的元素),则返回当前 `__nextIndex__` 的值,并将其自增 `1`,用于指向下一个待迭代元素的索引。 + // 如果以上条件都不满足,说明迭代已经完成,调用 `_unBind` 方法进行一些清理和解除绑定操作,然后返回 `undefined`,表示迭代结束。 _next: d(function () { var i; if (!this.__list__) return undefined; if (this.__redo__) { i = this.__redo__.shift(); - if (i !== undefined) return i; + if (i!== undefined) return i; } if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++; this._unBind(); return undefined; }), + // `next` 方法是符合迭代器协议的公开方法,用于获取下一个迭代元素的结果对象。 + // 它调用 `_next` 方法获取下一个元素的索引,然后将索引传递给 `_createResult` 方法来创建并返回包含 `done`(表示是否迭代完成)和 `value`(迭代元素的值)属性的结果对象。 next: d(function () { return this._createResult(this._next()); }), + // `_createResult` 方法用于根据传入的索引值创建迭代结果对象。 + // 如果索引值为 `undefined`,表示迭代已经完成,返回一个 `{ done: true, value: undefined }` 的对象,符合迭代器协议中迭代结束的表示形式。 + // 如果索引值不为 `undefined`,则表示还有元素可迭代,通过调用 `_resolve` 方法获取对应索引位置的元素值,并返回一个 `{ done: false, value: 元素值 }` 的对象, + // 表示迭代未结束且包含当前迭代元素的值。 _createResult: d(function (i) { if (i === undefined) return { done: true, value: undefined }; return { done: false, value: this._resolve(i) }; }), + // `_resolve` 方法用于根据索引值从 `__list__` 列表中获取对应的元素,简单地返回 `__list__` 数组中指定索引位置的元素, + // 是获取迭代元素实际值的一个辅助方法。 _resolve: d(function (i) { return this.__list__[i]; }), + // `_unBind` 方法用于解除迭代器与相关对象的绑定关系以及进行一些清理操作。 + // 首先将 `__list__` 属性设置为 `null`,表示不再关联列表数据,然后删除 `__redo__` 属性(如果存在)。 + // 如果存在 `__context__` 属性(即有绑定的上下文对象),则在上下文对象上移除对 `_add`、`_delete`、`_clear` 事件的监听(通过 `off` 方法,与之前的 `on` 方法对应), + // 最后将 `__context__` 属性也设置为 `null`,彻底解除与上下文的关联,完成清理和解除绑定的过程。 _unBind: d(function () { this.__list__ = null; delete this.__redo__; @@ -61,11 +114,22 @@ defineProperties( this.__context__.off("_clear", this._onClear); this.__context__ = null; }), + // `toString` 方法用于返回迭代器对象的字符串表示形式,遵循 `[object 类型名称]` 的格式, + // 如果对象定义了 `Symbol.toStringTag` 属性,则使用该属性的值作为类型名称,否则使用 `Object` 作为默认类型名称。 toString: d(function () { return "[object " + (this[Symbol.toStringTag] || "Object") + "]"; }) }, + // 使用 `autoBind` 函数(来自 `d/auto-bind` 模块)对 `_onAdd`、`_onDelete`、`_onClear` 这几个方法进行自动绑定操作, + // 使得这些方法内部的 `this` 指针始终指向当前迭代器实例,方便在事件触发等场景下正确访问和操作迭代器的属性和方法。 autoBind({ + // `_onAdd` 方法用于处理列表中元素添加的情况,它接收添加元素的索引 `index` 作为参数,逻辑如下: + // 如果添加元素的索引大于等于当前迭代器的 `__nextIndex__`(表示添加的元素在当前迭代位置之后,不会影响当前迭代过程),则直接返回,不做处理。 + // 如果添加元素的索引小于 `__nextIndex__`,说明添加的元素影响了当前的迭代顺序,需要调整迭代器的状态,将 `__nextIndex__` 自增 `1`,表示下一个迭代元素的索引往后移一位。 + // 如果不存在 `__redo__` 属性(可能之前没有需要重新处理的索引情况),则创建一个新的 `__redo__` 属性,它是一个数组,并将添加元素的索引 `index` 放入数组中, + // 这样后续迭代时可以根据这个数组来重新处理添加元素后的情况。 + // 如果已经存在 `__redo__` 属性,则遍历 `__redo__` 数组,对于每个元素 `redo`,如果它大于等于添加元素的索引 `index`,则将其自增 `1`, + // 表示这些需要重新处理的索引位置也需要往后移一位,以适应新添加的元素,最后将添加元素的索引 `index` 也添加到 `__redo__` 数组末尾。 _onAdd: d(function (index) { if (index >= this.__nextIndex__) return; ++this.__nextIndex__; @@ -78,17 +142,27 @@ defineProperties( }, this); this.__redo__.push(index); }), + // `_onDelete` 方法用于处理列表中元素删除的情况,接收要删除元素的索引 `index` 作为参数,逻辑如下: + // 如果要删除元素的索引大于等于当前迭代器的 `__nextIndex__`(表示删除的元素在当前迭代位置之后,不影响当前迭代过程),则直接返回,不做处理。 + // 如果要删除元素的索引小于 `__nextIndex__`,说明删除的元素影响了当前的迭代顺序,需要调整迭代器的状态,将 `__nextIndex__` 自减 `1`,表示下一个迭代元素的索引往前移一位。 + // 如果不存在 `__redo__` 属性(即之前没有需要重新处理的索引情况),则直接返回,因为没有需要调整的额外索引记录。 + // 如果存在 `__redo__` 属性,则先查找要删除元素的索引 `index` 在 `__redo__` 数组中的位置 `i`,如果找到(`i` 不为 `-1`),则从数组中删除该元素(通过 `splice` 方法)。 + // 接着遍历 `__redo__` 数组,对于每个元素 `redo`,如果它大于要删除元素的索引 `index`,则将其自减 `1`, + // 表示这些需要重新处理的索引位置需要往前移一位,以适应元素被删除后的情况。 _onDelete: d(function (index) { var i; if (index >= this.__nextIndex__) return; --this.__nextIndex__; if (!this.__redo__) return; i = this.__redo__.indexOf(index); - if (i !== -1) this.__redo__.splice(i, 1); + if (i!== -1) this.__redo__.splice(i, 1); this.__redo__.forEach(function (redo, j) { if (redo > index) this.__redo__[j] = --redo; }, this); }), + // `_onClear` 方法用于处理列表被清空的情况,逻辑如下: + // 如果存在 `__redo__` 属性(表示之前有需要重新处理的索引情况),则调用 `clear` 函数(来自 `es5-ext/array/#/clear` 模块,用于清空数组)清空 `__redo__` 数组。 + // 最后将 `__nextIndex__` 属性重置为 `0`,表示迭代器回到初始状态,等待新的列表数据进行迭代。 _onClear: d(function () { if (this.__redo__) clear.call(this.__redo__); this.__nextIndex__ = 0; @@ -97,6 +171,8 @@ defineProperties( ) ); +// 使用 `Object.defineProperty` 方法在 `Iterator` 函数的原型对象上定义一个 `Symbol.iterator` 属性, +// 其值是一个函数,该函数直接返回当前迭代器对象本身,这符合迭代器协议的要求,使得该迭代器对象可以被用于 `for...of` 循环等支持迭代器的语法结构中。 defineProperty( Iterator.prototype, Symbol.iterator, diff --git a/public/create-vote.html b/public/create-vote.html index fc29575..7f63e3f 100644 --- a/public/create-vote.html +++ b/public/create-vote.html @@ -1,235 +1,282 @@
+ + +