我已经解决了这个问题,但它需要一个O(N)解决方案。我的解决方案似乎也没有考虑到实际情况。任何人都可以解释为什么会这样吗?
在我写的一个简单的程序中(tic tac toe game), 我有一个“析构函数”功能,可以在游戏重置时重置所有变量。
特别是,我有两个“全局”变量(我知道块范围)。 我将其中一个设置为伪静态变量来重置“游戏板”。
var board = [11,12,13,21,22,23,31,32,33];
我用它来跟踪棋盘上占用的空间。
现在,当我重新启动游戏以破坏函数时,我使用了一个伪初始化的伪静态变量。
var staticBoard = [11,12,13,21,22,23,31,32,33];
因此,在使用staticBoard在这样的函数中重置板时,板会更新。
function destructor(){
board = staticBoard;
};
这适用于游戏的前几次迭代,但是后来在船上将无法更新,并且无论我多少次尝试析构函数都会保持不变。
我试过了。board = []; board = staticBoard;
。
但我会得到相同的结果。
最终,我认为javascript以某种方式混合了两个变量的内存地址,所以不是将它们设置为等于另外我做了这个。
function destructor(){
board = [];
staticBoard.forEach(function(element){
board.push(element);
});
这很有效,问题就停止了。
任何人都可以解释一下,如果可能的话还能提供更好的解决方案吗?
答案 0 :(得分:2)
这是因为当您执行board = staticBoard
时,您不会复制任何数据,而只需指定对相同数组的引用。简单说明:
xs = [1,2,3]
ys = xs
ys[2] = 4
xs //=> [1,2,4]
相反,你应该:
slice
:board = staticBoard.slice(0)
board = [11,12,13,21,22,23,31,32,33]
您可能希望使用Object.freeze
来阻止staticBoard
完全变异(但请注意,突变不会出错,只会无声地失败):
xs = Object.freeze([1,2,3])
ys = xs.slice(0)
xs[2] = 4
ys[2] = 5
xs //=> [1,2,3]
ys //=> [1,2,5]
然而,浅复制和冻结只能很好地工作,因为数组包含不可变的数字。如果内容是可变的,它也不会起作用:
xs = Object.freeze([[1]])
ys = xs.slice(0)
ys[0][0] = 2
xs //=> [[2]]
ys //=> [[2]]
答案 1 :(得分:0)
在Javascript中,对象变量本质上是指向内存位置的指针。当你这样做
obj1 = obj2
您只是将obj2
的内存位置分配给obj1
- 内存中的对象不会被复制。您应该创建一个数组的副本,这会创建一个 new 对象:
function destructor(){
board = staticBoard.slice(0);
};
这样,位于staticBoard
的对象永远不会变异,所以你可以一遍又一遍地引用它来获得原始电路板的新副本。
你也可以使用你发现的forEach
方法,但这有点难看; slice(0)
更简洁。