gpt4 book ai didi

Javascript 对象分配的奇怪行为

转载 作者:搜寻专家 更新时间:2023-11-01 00:17:31 24 4
gpt4 key购买 nike

我是 javascript 的新手(真的是整体编程的新手)。而我遇到了这种我不太理解的for/in循环的行为。以下代码片段在控制台中使用 $node 命令运行。

代码_0:

var result = {};
var list = ['A', 'B', 'C'];

for(var index in list){
var id = list[index];
result[id] = {};
result[id]['name'] = id;
}

console.log(result);

result_0:

{ A: { name: 'A' }, B: { name: 'B' }, C: { name: 'C' } }

代码_1:

var result = {};
var list = ['A', 'B', 'C'];
var INIT = {'a': 0, 'b': 0, 'c': 0,}

for(var index in list){
var id = list[index];
result[id] = INIT;
result[id]['name'] = id;
}

console.log(result);

result_1:

{ A: { a: 0, b: 0, c: 0, name: 'C' },
B: { a: 0, b: 0, c: 0, name: 'C' },
C: { a: 0, b: 0, c: 0, name: 'C' } }

我能理解为什么 code_0 会给出 result_0。但是 result_1 是我不明白的。我预计 result_1 是:

{ A: { a: 0, b: 0, c: 0, name: 'A' },
B: { a: 0, b: 0, c: 0, name: 'B' },
C: { a: 0, b: 0, c: 0, name: 'C' } }

code_0 和 code_1 有什么区别?为什么 code_1 会给出 result_1?

编辑:* 添加与问题相关的标签。 * 更改标题。 (标题曾经是关于for/in循环的)

最佳答案

在 Javascript 中,对象是通过引用(而不是复制)分配的。这是刚开始使用 Javascript 时容易混淆和学习的一个常见问题。

在您的 code_1 block 中,这行代码:

result[id] = INIT;

在循环的每次迭代中分配对完全相同对象的引用,因此它们都指向相同的对象并且都将具有相同的属性(因为它们都是相同的对象)。因此,对 result[id] 的任何进一步更改实际上只是对 INIT 的更改,INIT 是 result 中所有插槽正在使用的同一对象,因此它们似乎都在更改一次。

在 Javascript 中,如果你想在每次赋值中都有一个对象的单独副本,那么你必须在赋值之前创建一个新对象。在最新的浏览器中,您可以使用 Object.assign() 将可枚举属性从一个对象复制到另一个对象。

使用 Object.assign(),这是解决在分配对象之前制作对象副本的问题的一种方法:

var result = {};
var list = ['A', 'B', 'C'];
var INIT = {'a': 0, 'b': 0, 'c': 0,}

for(var index in list){
var id = list[index];
// make a new object that is a copy of INIT
var obj = Object.assign({}, INIT);
obj.name = id;
// put that new object into result[id]
result[id] = obj;
}

console.log(result);

对于旧版浏览器,这里有一个用于 Object.assign() 的 polyfill:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


这里有一个更简单的例子:

 var items = {a:1, b:2, c:3};

var list1 = items;
var list2 = items;

list1.a = 10;
console.log(items); // {a:10, b:2, c:3}
console.log(list1); // {a:10, b:2, c:3}
console.log(list2); // {a:10, b:2, c:3}
console.log(list1 === items); // true, they are the same object
console.log(list2 === items); // true, they are the same object

您可以看到所有三个变量都显示相同的值,因为它们都指向完全相同的对象,因此通过三个变量中的任何一个修改对象都会产生完全相同的更改。

关于Javascript 对象分配的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34540839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com