JavaScript中makeVector生成数组元素共享同一引用的问题求助
数组引用共享问题的分析与解决思路
问题根源
你遇到的核心问题是数组引用共享。在你的makeVector函数里,循环执行puzzle.push(row)时,每次添加的都是同一个row数组的引用,而非新创建的数组副本。这就导致puzzle里的所有元素本质上指向内存中的同一个数组——所以修改puzzle[0]时,其他元素看起来也跟着变了,其实它们本来就是同一个东西。
而直接声明的test数组不一样,每个子数组(比如[3,5,3]、[2,6,7])都是独立创建的新数组,互相没有引用关联,修改其中一个自然不会影响其他。
解决方案
只需要修改makeVector函数,每次向puzzle中添加元素时,创建row的浅副本即可。JavaScript里有几种简单的创建数组浅副本的方式:
- 使用扩展运算符:
[...row] - 使用
slice()方法:row.slice() - 使用
Array.from():Array.from(row)
修改后的makeVector函数如下:
const makeVector = function (row, n) { let puzzle = []; for (let i = 0; i < n; i++) { // 每次添加row的副本,而非原引用 puzzle.push([...row]); } return puzzle; };
这样puzzle里的每个元素都是独立的数组,修改其中一个就不会影响其他元素了。
额外的小修正
顺便提一下你代码里的两处小细节:
- 函数调用时,你写了
permuteRows(test[1], 2),但你的函数定义是permuteVector,应该改成permuteVector(test[1], 2); permuteVector里的p == 0判断放在循环外面更高效,且dequeue方法不需要传参数(你的Queue类里dequeue是无参的)。优化后的函数代码:
const permuteVector = function (row, p) { if (p === 0) return row; // 不需要移动直接返回 let q1 = new Queue(); // 1. 从向量创建队列 for (let i = 0; i < row.length; i++) { q1.enqueue(row[i]); } // 2. 将队列左移p位 for (let i = 0; i < p; i++) { let head = q1.head(); q1.enqueue(head); q1.dequeue(); } // 3. 将队列元素写回原向量 row.splice(0, row.length, ...q1.show()); };
现在再执行permuteVector(puzzle[0], 1),就只会修改puzzle[0],其他元素完全不受影响了。
内容的提问来源于stack exchange,提问作者H3nryk
相关产品推荐
相关产品推荐

