JavaScript可通过实现Symbol.iterator为多维数组定制扁平化遍历器,支持for...of等语法;核心是返回符合迭代器协议的next()方法,按需递归展开嵌套结构,节省内存。

JavaScript 中可以通过实现 Symbol.iterator 方法,为多维数组或矩阵对象定制一个扁平化遍历器,使其支持 for...of、扩展运算符([...matrix])、解构等原生迭代语法。
核心思路:递归展开 + 迭代器协议
关键在于让对象返回一个符合迭代器协议的 next() 方法,该方法每次返回下一个扁平元素。不需要生成完整新数组,而是按需计算,节省内存。
- 遍历逻辑用递归或栈模拟递归处理嵌套结构
- 迭代器状态需自行维护(如当前索引、待处理子项栈)
- 必须返回形如
{ value: ..., done: true|false }的对象
为普通多维数组写一个可复用的扁平迭代器类
下面是一个通用 FlatIterator 类,接受任意嵌套数组,深度默认无限(可选限制):
class FlatIterator {
constructor(array, depth = Infinity) {
this.stack = [{ arr: array, index: 0 }];
this.depth = depth;
}
<p>next() {
while (this.stack.length > 0) {
const { arr, index } = this.stack[this.stack.length - 1];</p><pre class="brush:php;toolbar:false;"> if (index >= arr.length) {
this.stack.pop();
continue;
}
this.stack[this.stack.length - 1].index = index + 1;
const item = arr[index];
if (Array.isArray(item) && this.depth > 0) {
this.stack.push({ arr: item, index: 0 });
this.depth--;
} else {
return { value: item, done: false };
}
}
return { value: undefined, done: true };}
[Symbol.iterator]() { return this; } }
使用示例:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
const matrix = [[1, 2], [3, [4, 5]], 6];
const iter = new FlatIterator(matrix);
<p>for (const val of iter) {
console.log(val); // 1, 2, 3, 4, 5, 6
}</p><p>console.log([...new FlatIterator(matrix)]); // [1, 2, 3, 4, 5, 6]</p>
为自定义 Matrix 类直接内置扁平迭代能力
如果你封装了矩阵类(如 class Matrix { ... }),可直接在原型上定义 Symbol.iterator:
class Matrix {
constructor(data) {
this.data = data;
}
<p>*[Symbol.iterator]() {
const stack = [{ arr: this.data, index: 0 }];
while (stack.length > 0) {
const { arr, index } = stack[stack.length - 1];
if (index >= arr.length) {
stack.pop();
continue;
}
stack[stack.length - 1].index = index + 1;
const item = arr[index];
if (Array.isArray(item)) {
stack.push({ arr: item, index: 0 });
} else {
yield item;
}
}
}
}</p><p>// 使用
const mat = new Matrix([[1, 2], [3, 4]]);
console.log([...mat]); // [1, 2, 3, 4]</p>
注意:这里用了 function* 语法(生成器函数),它天然返回符合协议的迭代器,代码更简洁、易读,且自动管理状态。
注意事项与优化点
实际使用中要注意几个细节:
- 避免深递归导致栈溢出 —— 显式栈(如上面的
stack数组)比纯递归更安全 - 若需支持
Array.from(iter)或其他迭代消费方式,确保next()正确响应多次调用 - 如果矩阵是固定二维(如
[[r1], [r2], ...]),可用双循环替代递归,性能更高 - 想跳过空值或过滤特定类型?在
yield前加判断即可,比如if (item != null) yield item;
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










