JavaScript函数参数引用对象

JavaScript函数参数引用对象,javascript,node.js,Javascript,Node.js,我一直在创建一个类似于agar.io的游戏,但在将对象传递到函数时注意到一些奇怪的行为 我简化了代码以突出问题。在代码中,我将对象gameData作为参数传递到update,但当我在函数中更改参数时,它将更改传递到引用的对象 如果您运行代码,打印到控制台的gameData对象将继续增加,尽管不会直接更改它 我不确定这里发生了什么,我想了解为什么会发生这种情况,以及如何避免这种情况。我已经设法用绳子把它修好了 update({x: gameData.x, y: gameData.y}) 但这不是

我一直在创建一个类似于
agar.io
的游戏,但在将对象传递到函数时注意到一些奇怪的行为

我简化了代码以突出问题。在代码中,我将对象
gameData
作为参数传递到
update
,但当我在函数中更改参数时,它将更改传递到引用的对象

如果您运行代码,打印到控制台的
gameData
对象将继续增加,尽管不会直接更改它

我不确定这里发生了什么,我想了解为什么会发生这种情况,以及如何避免这种情况。我已经设法用绳子把它修好了

update({x: gameData.x, y: gameData.y})
但这不是干净的代码,也不能解释行为

问候,, 老茧 实时代码输入

更新({x:gameData.x,y:gameData.y})

此行创建了一个包含
x
y
属性的新对象,您可以将其传递给
update
函数,但
gameData
是您正在使用的全局变量。因此,当使用刚刚创建的新对象调用update时,会更新该新对象的值,并且在函数调用后不会将其保存在任何位置

但是

更新(游戏数据)

获取gameData对象作为参数,并更新引用在代码顶部定义的全局变量的
gameData
对象的
x
y
值,在
console.log(gameData)
中可以看到此对象中的值

注:

我不建议使用全局变量并调用不返回任何内容的函数,相反,您可以创建如下函数:

function update(data){
    return { x: data.x + 1, y: data.y + 1 }
}
gameData = update(gameData)
这样称呼它:

function update(data){
    return { x: data.x + 1, y: data.y + 1 }
}
gameData = update(gameData)

我觉得这个例子很有趣。我将尝试详细解释它是如何工作的

正如我们所看到的,我们的代码两次调用了
update()
函数,然而,
gameData
对象只更新了一次

让我们看看:

function heartbeat() {
    update({x: gameData.x, y: gameData.y});  // I see this as a getter
    update(gameData);                        // I see this as a setter
}
对于第一次调用,我们实际上以对象的形式传递
gameData.x
gameData.y
基本值。它们实际上只是基本值,而不是引用。我们对这些基本值所做的任何操作都不会影响存储在内存中某处的实际对象


对于第二次调用,我们传递了
gameData
对象的引用,因此,当您将
gameData.x
gameData.y
属性重新指定给新值时,它们直接影响内存中的实际对象。这就是为什么我们在调用
console.log(gameData)
时会收到这些属性的新值

这就是JavaScript(和许多其他语言)的工作方式。作为值的对象实际上是对该对象的引用。想象一下,如果对象在传递到函数时被复制,会对性能产生什么影响。啊,谢谢,这很有意义。函数最初返回了对象,您可以看到它被注释掉的位置。但是,我注意到,当我删除return语句时,它仍然正常工作。我就是不明白为什么它会这样。干杯…@Callum如果得到答案,你可以将答案标记为正确!还要注意的是,使用全局变量总是很危险的,如果你想做大事,可能会导致一些严重的问题