
本文揭示了 JavaScript 中 const 声明的数组虽不可重新赋值,但其内部元素仍可被修改,从而引发多处调用同一函数时产生意外副作用的问题,并提供彻底隔离状态的核心修复方案。
本文揭示了 javascript 中 `const` 声明的数组虽不可重新赋值,但其内部元素仍可被修改,从而引发多处调用同一函数时产生意外副作用的问题,并提供彻底隔离状态的核心修复方案。
问题根源在于对 const 的常见误解:const DEFAULT_BLOCK_GRID = [[...], [...], [...]] 仅保证变量 DEFAULT_BLOCK_GRID 的引用不可变更,并不冻结其内部嵌套数组的内容。因此,当 createBlock() 多次执行并反复写入 newBlock[i][j] = true 时,实际是在持续修改同一份内存中的 DEFAULT_BLOCK_GRID 实例——所有后续调用都基于已被污染的“模板”,最终导致所有返回值趋同为最后一次写入的结果(如 [ [true,true,true,true], [true,true,true,true], [true,true,true,false] ])。
根本解法是确保每次调用 createBlock() 都获得一份全新的、独立的网格副本。将 DEFAULT_BLOCK_GRID 移入函数作用域内,并通过深拷贝或结构化初始化生成新数组:
function createBlock(block) {
// ✅ 每次调用都创建全新网格实例,彻底避免共享状态
const DEFAULT_BLOCK_GRID = [
[false, false, false, false],
[false, false, false, false],
[false, false, false, false]
];
// 使用 map + slice 实现浅拷贝(适用于本例中一维布尔值)
const newBlock = DEFAULT_BLOCK_GRID.map(row => [...row]);
for (let i = 0; i < newBlock.length; i++) {
if (i >= block.length) break;
for (let j = 0; j < newBlock[i].length; j++) {
if (j >= block[i].length) break;
if (block[i][j] === true) {
newBlock[i][j] = true;
}
}
}
return newBlock;
}⚠️ 注意事项:
Alibabacloud Sdk Client Initialization For Java下载在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 原代码中存在逻辑错误:
block.length[i] 应为 <code>block[i].length (否则会触发 <code>undefined访问);- 若
block结构更复杂(含嵌套对象),需改用JSON.parse(JSON.stringify())或结构克隆(如structuredClone)实现深拷贝;createListOfBlocksGrid()中BlocksGrid.push(value)推入的是原始BLOCKS_MATRIX值而非生成结果,应修正为BlocksGrid.push(block)才符合语义。
总结:在函数式编程实践中,纯函数(Pure Function)要求不产生副作用、不依赖外部可变状态。将默认数据声明移入函数内部、显式创建新实例,是保障函数行为稳定、可预测与可测试的关键实践。
立即学习“Java免费学习笔记(深入)”;


















