2

我不知道如何解释这一点,这真的很困扰我。它弄乱了我的很多代码。无论如何,基本上就是这样。假设我有一个包含一些值的结构的变量,比如默认设置:

var DefaultValues = {
    username: "cakeisajoke",
    this: "is some",
    default: {
        data: 483
    },
    lives: 3,
    playerX: 0,
    playerY: 0
}

在我的代码中,我将此变量用作“模板”,因此我可以更轻松地重置我的游戏。像这样:

var GameValues = DefaultValues;

好的,到目前为止,这是有道理的。现在,假设玩家失去生命:

GameValues.lives--;

或者,玩家移动一些:

GameValues.playerX += 20;
GameValues.playerY -= 10;

所以,现在我的 GameValues 改变了,我将游戏设置为这个。但是,然后玩家失败了,游戏结束了。如果他想再次玩,我所要做的就是将 GameValues 变量重置为默认值:

GameValues = DefaultValues;

而且,就我而言,这应该只是将 GameValues 设置为 DefaultValues,对吗?但是,事实并非如此。出于某种原因,GameValues 和 DefaultValues 现在具有相同的值,而实际上它们不应该。例如,DefaultValues 现在是 0,而不是原来的 1。

为什么要这样做?我已经看了,又看了一遍,除了那个初始结构之外,我没有在代码中的任何地方设置 DefaultValues。

“我以这个和默认值为例,我知道我实际上不能使用它们,因为它们是保留的”

4

5 回答 5

1

这是因为 javascript 使用对象的引用。因此,将一个对象分配给另一个对象只会使它们指向同一个对象。你需要克隆对象,这个线程描述了一些方法来做到这一点。

var GameValues = DefaultValues; //Both variables reference the same object
GameValues.lives--; //Since they both reference the same object this will change both the variables so to say

还要考虑不使用单词thisdefault作为键,它们是保留关键字。

于 2013-11-11T08:17:35.990 回答
1

您当前的问题是因为javascript 使用 objects 的引用

对于这种方法之王,您可以使用像这样的其他 js 模式

var DefaultValues = {
    username: "cakeisajoke",
    "this" : "is some",
    default: {
        data: 483
    },
    lives: 3,
    playerX: 0,
    playerY: 0
}

var GameValues =  Object.create(DefaultValues);

你可以做

GameValues.lives--;
GameValues.playerX += 20;
GameValues.playerY -= 10;

无需更改默认值。

值得看看这个modeling-patterns-for-javascript-browserbased-games

于 2013-11-11T08:24:38.273 回答
1

创建DefaultValues对象时,您会在内存中创建一个对象,并在变量中创建对该对象的引用:DefaultValues

+---------------+ +--------------+
| 默认值 |--------------->| 用户名:“cakeisajoke” |
+---------------+ | 寿命:3 |
                                 | (等等)|
                                 +--------------+

当你这样做时:

var GameValues = DefaultValues;

您只是将对对象的引用存储在第二个变量中。现在你有了这个:

+---------------+
| 默认值 |---+
+---------------+ | +--------------+
                    | | 用户名:“cakeisajoke” |
                    +----------->| 寿命:3 |
                    | | (等等)|
+---------------+ | +--------------+
| 游戏价值 |---+
+---------------+

您没有 的副本DefaultValues您只有对该对象的两个引用。您对对象所做的更改会更改对象,因此无论您使用哪个引用自然都是可见的。

于 2013-11-11T08:25:03.603 回答
0

当您执行 assignmentvar a = {}时,JavaScript 存储a对新创建对象的引用,而不是其值,这就是为什么当您通过 更改设置时GameValues,设置DefaultValues也在更改:这两个是对同一对象的引用。

当您初始化原始类型的新变量时,例如var i = 1;,它存储在i实际值中,因此

var i = 1;
var b = i;
var b += 4; // b is 5, i is still 1   

为了解决您的特定任务,您可以编写一个遍历对象的递归函数,并复制每个键值对。请参阅这篇文章,它应该为您提供一些关于如何做到这一点的见解。

于 2013-11-11T08:17:50.757 回答
0

因为DefaultValues是一个对象,当你将它分配给GameValues你时,实际上只是分配了一个对它的引用,而不是复制对象本身。这意味着当您设置一个属性时,更改将反映在另一个中。

您可以通过将属性从 on 复制来解决此问题,而不是在一个作业中进行DefaultValueGameValue这是一个基本示例,但请注意,您也必须处理嵌套对象:

Object.keys(DefaultValues).forEach(function (key) {
    GameValues[key] = DefaultValues[key];
});
于 2013-11-11T08:18:53.040 回答