对象引用如何在javascript内部工作

时间:2015-01-24 16:26:05

标签: javascript node.js

我是javascript的新手。 我写了简单的代码:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

正如所料,它打印:

[ { a: [ 'a' ] } ]

但是,当我将以下行附加到上一个代码时:

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

我原以为要打印:

[ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

但它打印出来:

[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

意外结果的整个代码:     var temp = {}     var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

为什么数组的第一个元素已更新?

以下代码给出了我预期的结果:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);

如何在此处添加temp = {}

4 个答案:

答案 0 :(得分:2)

Javascript中的对象通过引用传递 。也就是说,只创建了一个对象,并且可以使用表示该对象的符号,但它始终引用同一个对象。

让我们深入了解一下:

如果我理解你的例子是正确的,那么这部分

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
console.log(arr);

创建一个向其添加temp的本地变量['a']。然后你将其推入arr。

所以在这一点上,arr引用了对象temp,看起来像这样:

[ { a: [ 'a' ] } ]

执行此操作时:

temp['b'] = ['b']
arr.push(temp);
console.log(arr);

指向包含temp的原始对象的['a']符号已更新,因此arr也会更新,因此arr包含此内容:

[ { a: [ 'a' ], b: [ 'b' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

最后,

然后你这样做:

temp = {};
temp['a'] = ['a']
temp['b'] = ['b']
arr.push(temp);
console.log(arr);

这会创建一个单独的全局变量temp,您可以在其上添加两者 ['a']['b']。这是全局的,因为在声明/初始化中没有 var关键字。然后将其推入arr。但是,由于它是一个全局变量,而不是原始的本地变量,所以你会看到这一点:

 [ { a: [ 'a' ] }, { a: [ 'a' ], b: [ 'b' ] } ]

答案 1 :(得分:1)

在第一种情况下,arr[0]temp个参考,arr[1]也有temp的参考。因此,arr[0]arr[1]具有相同的引用。

因此,更新引用将在引用所在的任何位置更新它 被推荐。

然而,在第二种情况下,当您执行temp = {}时,您只需将temp重新分配到引用,然后再推送它。因此,arr[0]的引用之间没有任何关系,因此现在更新temp只会影响它。

答案 2 :(得分:1)

JavaScript中有两种数据类型 - 值类型和引用类型。

值类型实际上是在对象之间发送时复制的。这是因为这是你对数字和布尔等特定事物的预期。

假设我将数字1传递给将其存储在对象A中的函数。

如果我随后可以通过修改原始数字的值来随后修改A中包含的值,那将是令人惊讶的。因此,通过价值。还可以对值类型执行优化。

对象(即所有除了数字文字,布尔文字,空,未定义和字符串文字*)是JavaScript中的引用类型,只传递它们的引用。这主要是出于效率原因。在您的示例中,temp是一个对象。因此,它通过引用传递。

所以

temp['b'] = ['b']

修改temp的单个现有实例,从而在之前修改arr的内容,然后将temp推送到arr第二次。

因此,您最终会得到一个包含对单个对象temp的两个引用的数组,从而为您提供观察到的结果。

*我有意忽略了字符串实现的一些复杂性。

答案 3 :(得分:0)

示例不一样,与temp = {}没有关系。

在第一个示例中,您将temp推了两次,这意味着arr必须引用2 temp

在第一个push之后,您将另一个项目添加到temp,因此在arr内,如果您打印过它,您会看到:

[ { a: [ 'a' ], b: [ 'b' ] } ]

所以在控制台上尝试一下:

var temp = {}
var arr = []

temp['a'] = ['a']
arr.push(temp)
temp['b'] = ['b']
console.log(arr);

你会看到结果:

[ { a: [ 'a' ], b: [ 'b' ] } ]

将另一个temp推入arr只会导致对temp的两次引用。