JavaScript函数参数引用对象

时间:2018-10-05 14:01:02

标签: javascript node.js

我一直在创建类似于from collections import namedtuple a = ['a0', 'a1', 'a22'] b = ['b', 'b11111', 'b2'] c = ['', 'c', 'c333333333'] def func(**kwargs): nt = namedtuple('nt', ['a', 'b', 'c']) for x in kwargs['a']: for y in kwargs['b']: for z in kwargs['c']: if len(x) >= len(y) >= len(z) > 10: return nt(a_header=x, b_header=y, c_header=c, all_len=len(x) + len(y) + len(z)) return () # it should return len('a22') + len('b11111') + len('c333') 的游戏,但是在将对象传递到函数中时注意到一些奇怪的行为。

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

如果您运行代码,则尽管没有直接更改它,但正在打印到控制台的update对象将继续增加。

我不确定这是怎么回事,我想了解为什么会发生这种情况以及如何解决它。我设法用线修复了它

gameData

但这不是干净的代码,也无法解释其行为。

关于, 卡勒姆 jsfiddle

中的实时代码
update({x: gameData.x, y: gameData.y})

2 个答案:

答案 0 :(得分:1)

  

update({x:gameData.x,y:gameData.y});

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

但是

  

update(gameData);

获取gameData对象作为参数,并更新引用在代码顶部定义的全局变量的x对象的ygameData值,以及何时在console.log(gameData)中,您将看到该对象中的值。

注意:

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

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

并这样称呼它:

gameData = update(gameData)

答案 1 :(得分:1)

我认为这个例子非常有趣。我将尝试详细解释其工作原理。

我们看到,我们的代码调用了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.xgameData.y原始值。它们实际上只是原始值,不是引用。我们对这些原始值进行的任何操作都不会影响存储在内存中某个地方的实际对象。

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