首页 > 解决方案 > Javascript混合内存地址?(重置数组不起作用)

问题描述

我已经解决了这个问题,但它需要一个 O(N) 解决方案。我的解决方案似乎也没有考虑到实际情况。谁能解释为什么会这样?

在我正在编写的一个简单程序(井字游戏)中,我有一个“析构函数”函数,它会在游戏重置时重置所有变量。

特别是,我有两个“全局”变量(我知道块范围)。我将其中一个设置为伪静态变量以重置“游戏板”。

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);
});

这有效,问题停止了。

谁能解释一下,如果可能的话,还可以提供更好的解决方案吗?

标签: javascript

解决方案


这是因为您在复制时没有复制任何数据board = staticBoard,您只是将引用分配给同一个数组。简单说明:

xs = [1,2,3]
ys = xs
ys[2] = 4
xs //=> [1,2,4]

相反,您应该:

  • 浅拷贝数组sliceboard = 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]]

推荐阅读