我已经解决了这个问题,但它需要一个O(N)解。我的解决方案似乎也没有考虑到实际情况。有人能解释为什么会发生这种情况吗?
在我正在编写的一个简单程序(tic tac toe游戏)中,我有一个"destructor“函数,它在游戏重置时重置所有变量。
特别是,我有两个“全局”变量(我知道块作用域)。我将其中一个设置为伪静态变量来重置“游戏板”。
var board = [11,12,13,21,22,23,31,32,33];我用它来跟踪黑板上占用的空间。
现在,当我重新启动游戏以销毁函数时,我使用了一个伪静态变量,它是在as中初始化的。
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);
});这起作用了,问题也就解决了。
有没有人可以解释一下这一点,如果可能的话,还能提出一个更好的解决方案吗?
发布于 2018-05-18 09:50:17
这是因为在执行board = staticBoard时,您不会复制任何数据,而只是将引用分配给同一数组。简单说明:
xs = [1,2,3]
ys = xs
ys[2] = 4
xs //=> [1,2,4]相反,您应该执行以下任一操作:
将包含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]]发布于 2018-05-18 09:45:55
在Javascript中,对象变量本质上是指向内存位置的指针。当你这样做的时候
obj1 = obj2您只是将obj2的内存位置分配给obj1 -内存中的对象不会被复制。您应该创建数组的副本,这将创建一个新对象:
function destructor(){
board = staticBoard.slice(0);
};这样,位于staticBoard的对象永远不会发生变化,因此您可以一遍又一遍地引用它,以获得原始板的新的干净副本。
正如您所发现的,您也可以使用forEach方法,但这有点难看;slice(0)要简洁得多。
https://stackoverflow.com/questions/50402651
复制相似问题