可通过实现[symbol.iterator]让自定义对象支持for...of;reversearray类封装反向视图,不修改原数组,仅迭代时倒序取值,兼容解构、扩展运算符及链式惰性操作。

JavaScript 中可以通过实现 [Symbol.iterator] 方法,让自定义对象支持 for...of 遍历;要支持倒序遍历,关键不是改原生数组,而是封装一个可迭代的“反向视图”对象——它不修改原数组,只在迭代时按索引从后往前取值。
创建一个支持倒序遍历的包装类
定义一个 ReverseArray 类,接收原始数组,在其原型上部署 [Symbol.iterator],返回一个从末尾开始的迭代器:
- 构造函数保存原始数组引用,不做拷贝,保持轻量
-
[Symbol.iterator]返回一个闭包函数,内部维护当前索引(初始为arr.length - 1),每次调用next()递减索引并返回对应元素 - 当索引小于 0 时,返回
{ done: true }
示例代码:
class ReverseArray {
constructor(arr) {
this.arr = Array.isArray(arr) ? arr : [];
}
*[Symbol.iterator]() {
for (let i = this.arr.length - 1; i >= 0; i--) {
yield this.arr[i];
}
}
}
<p>// 使用
const nums = [1, 2, 3, 4];
const reversed = new ReverseArray(nums);</p><p>for (const item of reversed) {
console.log(item); // 输出:4 → 3 → 2 → 1
}</p>支持解构与扩展运算符
因为实现了标准迭代协议,ReverseArray 实例天然兼容解构赋值和 [...spread]:
-
const [a, b, ...rest] = new ReverseArray([10, 20, 30]);→a=30, b=20, rest=[10] -
const copy = [...new ReverseArray([1, 2, 3])];→[3, 2, 1]
无需额外适配,这是 Iterator 协议带来的统一行为。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
可链式调用的增强工具(如 reverseMap、reverseFilter)
若想进一步封装常用操作,可在 ReverseArray 上添加方法,返回新的 ReverseArray 实例(保持惰性、不可变):
-
reverseMap(fn):对倒序遍历时每个元素执行映射,返回新ReverseArray -
reverseFilter(predicate):倒序遍历中筛选符合条件的元素(注意:筛选后仍保持倒序逻辑,即原数组末尾满足条件的先出)
实现要点:这些方法不立即执行,而是返回一个“延迟计算”的新包装器,其 [Symbol.iterator] 内部组合原迭代逻辑与转换逻辑。
注意事项与边界情况
使用时需留意几点:
- 原数组被修改后,
ReverseArray实例会反映最新状态(因持有引用),如需快照应传入[...arr] - 空数组或非数组输入应在构造函数中处理(如默认为空数组),避免运行时报错
- 不建议直接给
Array.prototype添加方法(污染全局),推荐用包装类或工厂函数方式
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










