JS函数createBlock调用异常:单独调用正常,联动调用出错
问题分析与修复方案
核心问题1:数组引用共享导致的污染
JavaScript中数组属于引用类型,你的createBlock函数里let newBlock = DEFAULT_BLOCK_GRID并没有创建新的数组副本,只是让newBlock指向了DEFAULT_BLOCK_GRID的内存地址。每次调用createBlock都会直接修改原DEFAULT_BLOCK_GRID数组,后续所有调用都会基于这个被修改过的数组继续操作,最终所有返回结果都会变成最后一次修改后的状态——这就是为什么单独调用正常,但调用createListOfBlocksGrid后所有结果都出错的原因。
核心问题2:createListOfBlocksGrid的错误推送逻辑
在createListOfBlocksGrid函数中,你调用createBlock(value)生成了目标数组block,但最后执行BlocksGrid.push(value)时,推送的是BLOCKS_MATRIX里的原始值,而不是生成后的block数组,完全偏离了函数的预期目的。
修复后的完整代码
const BLOCKS_MATRIX = {1: [[true]], 2: [[true,true]], 3: [[true,true],[false,true]], 4: [[true,true,true]], 5: [[true,true,true, true]], 6: [[false, false, true],[true,true,true]], 7: [[true, true, false], [false, true, true]], 8: [[true, true], [true, true]], 9: [[false, true, false], [true, true, true]], 10: [[false, true, true], [true, true, false], [false, true, false]], 11: [[true, true, true, true, true]], 12: [[true, true, true, true], [false, false, false, true]], 13: [[true, true, true, false], [false, false, true, true]], 14: [[true, true, true], [false, true, true]], 15: [[true, true, true], [false, true, false], [false, true, false]], 16: [[true, true, true], [true, false, true]], 17: [[true, true, true], [false, false, true], [false, false, true]], 18: [[false, false, true], [false, true, true], [true, true, false]], 19: [[false, true, false], [true, true, true], [false, true, false]], 20: [[true, true, true, true], [false, false, true, false]], 21: [[true, true, false], [false, true, false], [false, true, true]]} const DEFAULT_BLOCK_GRID = [[false, false, false, false], [false, false, false, false], [false, false, false, false]] function createBlock(block) { // 复制DEFAULT_BLOCK_GRID的二维数组副本,避免引用共享 let newBlock = DEFAULT_BLOCK_GRID.map(row => [...row]) for (let i = 0; i < DEFAULT_BLOCK_GRID.length; i++) { if (block.length <= i) break; for (let j = 0; j < DEFAULT_BLOCK_GRID[i].length; j++) { // 修正判断条件:应该是block[i].length <= j,不是block.length[i] if (block[i].length <= j) break; if (block[i][j] === true) { newBlock[i][j] = true; } } } return newBlock } console.log("Test") console.log(createBlock([ [true, true], [false, true] ])) function createListOfBlocksGrid() { let BlocksGrid = [] let block; for (const [key, value] of Object.entries(BLOCKS_MATRIX)) { block = createBlock(value) // 推送生成后的block数组,而非原始value BlocksGrid.push(block) } return BlocksGrid } console.log(createListOfBlocksGrid())
额外修正点
还修复了createBlock中的一个小bug:原代码里的if (block.length[i] <= j)是错误的,应该是if (block[i].length <= j)——因为block是二维数组,block[i]才是当前行的数组,block.length是行数,不能用block.length[i]来获取行长度。
内容的提问来源于stack exchange,提问作者levoo777
相关产品推荐
相关产品推荐

