对象引用如何在 javascript 内部工作
How do object references work internally in javascript
我对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 = {}
在这里有什么帮助?
Javascript 中的对象是通过引用传递的。 也就是说,只创建一个对象,并且可以使用表示该对象的符号,但它将始终引用同一对象。
让我们更深入地了解一下:
如果我理解你的例子是正确的,这部分
var temp = {}
var arr = []
temp['a'] = ['a']
arr.push(temp)
console.log(arr);
创建要向其添加['a']
的局部变量temp
。 然后你把它推到arr。
因此,此时,arr
引用对象temp
,如下所示:
[ { a: [ 'a' ] } ]
执行此操作时:
temp['b'] = ['b']
arr.push(temp);
console.log(arr);
指向包含['a']
的原始对象的temp
符号将更新,因此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' ] } ]
一种情况下,arr[0]
有temp
的引用,arr[1]
也有temp
的引用。因此,arr[0]
和arr[1]
具有相同的参考。
因此,更新引用将在引用所在的任何位置更新它被推荐。
但是,在第二种情况下,当您执行temp = {}
时,您只需在推送新引用之前将temp
重新分配给新引用。因此,arr[0]
的引用之间没有关系,因此现在更新temp
只会影响它。
例子不一样,与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
。
JavaScript 中有两种数据类型 - 值类型和引用类型。
值类型实际上是在对象之间发送时复制的。这是因为这是您对某些事物(如数字和布尔值)的期望。
假设我将数字1
传递给一个函数,该函数将其存储在对象A
中。
如果我随后可以通过修改原始数字的值来修改A
中包含的值,那将是令人惊讶的。因此,按值传递。还可以对值类型执行优化。
对象(即除数字文字、布尔文字、null、undefined 和字符串文字*之外的所有内容)是 JavaScript 中的引用类型,只有它们的引用被传递。这主要是出于效率原因。在您的示例中,temp
是一个对象。因此,它通过引用传递。
所以
temp['b'] = ['b']
修改 temp
的单个现有实例,从而修改 arr
的内容,然后再再次将temp
推送到arr
。
所以你最终得到一个数组,其中包含对单个对象temp
的两个引用,给你观察到的结果。
* 字符串实现有一些复杂性,我在这里故意忽略了这些复杂性。
- JS Promises如何在内部工作
- 为什么更改范围获胜'不能在ng if内部工作,而是通过函数调用AngularJS
- Array.prototype.stice.call()的内部工作
- 承诺内部工作
- .htaccess和.htpasswd的内部工作方式
- 对象引用如何在 javascript 内部工作
- 无法获得控制台.log在 CasperJS 中评估内部工作
- Javascript Array Push 代码如何在内部工作
- jQuery Content Switcher (无法使联系人表单在内部工作)
- GetVariable在方法内部工作
- Br在使用Jquery.html()时无法在P内部工作
- yeoman生成器:复制或模板dos'不能在异步回调内部工作
- 了解$.proxy如何在内部工作
- 为什么$(this)选择器在我的函数内部工作,而在外部工作
- canvas.width=canvas.width如何在内部工作
- Javascript事件驱动的内部工作原理
- setInterval只在if(){}块内部工作
- Jquery不能在函数内部工作
- Jquery平滑滚动只在内部工作
- 使用ng-bind-html时,Ng-click不能在控制器内部工作