JavaScript 变量在没有指令的情况下写入其他变量
JavaScript Variables writing to other variables with no instruction?
我不知道如何解释这一点,这真的很困扰我。它弄乱了我的很多代码。无论如何,这里基本上就是这样。假设我有一个变量,它保存了一个带有一些值的结构,比如默认设置:
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 = DefaultValues;
而且,就我而言,这应该只是将游戏值设置为默认值,对吧?但是,事实并非如此。出于某种原因,游戏值和默认值现在具有相同的值,而它们不应该具有相同的值。例如,默认值现在是 0,而不是原来的 1。
为什么要这样做?我看了又看了一遍,除了那个初始结构之外,我没有在代码中的任何位置设置 DefaultValues。
"我用这个和默认值作为例子,我知道我实际上不能使用它们,因为它们是保留的"
这是因为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
还要考虑不要使用单词 this
和 default
作为键,它们是保留关键字。
创建 DefaultValues
对象时,会在内存中创建一个对象,并在 DefaultValues
变量中创建对该对象的引用:
+---------------+ +-------------------------+|默认值 |--------------->|用户名: "蛋糕樱桃" |+---------------+ |生命数: 3 | |(等等) | +-------------------------+
执行此操作时:
var GameValues = DefaultValues;
您只需将对对象的引用存储在第二个变量中。现在你有这个:
+---------------+|默认值 |---++---------------+ | +-------------------------+ | |用户名: "蛋糕樱桃" | +----------->|生命数: 3 | | |(等等) |+---------------+ | +-------------------------+|游戏价值 |---++---------------+
您没有DefaultValues
的副本,您只有对对象的两个引用。对对象所做的更改会更改对象,因此无论使用哪个引用,自然可见。
您当前的问题是因为javascript使用对象的引用。
对于这种方法之王,您可以使用其他 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;
没有改变定义。
值得一看的是,这个基于javascript浏览器的游戏的建模模式是值得的
DefaultValues
是一个对象,所以当你把它分配给GameValues
时,你实际上只是在分配对它的引用,而不是复制对象本身。这意味着当您设置一个属性时,更改将反映在另一个属性中。
您可以通过将属性从DefaultValue
复制到GameValue
而不是在一个分配中执行此操作来解决此问题。下面是一个基本示例,但请注意,您还必须处理嵌套对象:
Object.keys(DefaultValues).forEach(function (key) {
GameValues[key] = DefaultValues[key];
});
当你做赋值var 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
为了解决您的特定任务,您可以编写一个递归函数,该函数将遍历对象,并复制每个键值对。请参阅本文,它应该为您提供有关如何执行此操作的一些见解。
- 我希望在不替换现有变量的情况下恢复localStorage中的变量
- 如何在没有ajax的情况下将javascript动态数据发送到php变量
- 如何在不保存到其他变量的情况下更改JavaScript中的值
- 在我的情况下,使用带有变量失败的 jquery 选择器
- 连接变量,在我的情况下背景样式损坏
- AngularJS在不使用变量的情况下将服务注入模块中,这样就可以缩小它
- 如何在没有表单提交、没有js、没有jquery和没有ajax的情况下将输入的文本框值存储到php变量中
- 如何在不赋值数组变量的情况下读取数组数据
- 如何在不定义变量的情况下使用 document.createElement()
- 在 jQuery 不起作用的情况下迭代变量
- 在不中断形式帖子的情况下在角度中设置变量
- Javascript变量在没有var的情况下工作
- 在不重新加载页面的情况下,从JSP(服务器端)b设置一个JavaScript变量
- 在这种情况下,如何使变量全局可访问
- 如何在不使用for循环的情况下增量增加变量的值
- Rails/JS-在不刷新页面的情况下获取变量
- 在不引起递归的情况下将两个淘汰变量连接在一起
- 在这种情况下,我可以使用 JS 变量吗以及如何使用
- 在没有ajax的情况下将多个变量传递到引用页面的最佳方式
- 如何在没有web服务器的情况下将变量数据从Python传输到Javascript