当前位置:  开发笔记 > 编程语言 > 正文

Javascript对象赋值的奇怪行为

如何解决《Javascript对象赋值的奇怪行为》经验,为你挑选了1个好方法。

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

code_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' } }

code_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循环)



1> jfriend00..:

在Javascript中通过引用(而不是通过复制)分配对象.这是第一次在Javascript中加速时混淆和学习的常见问题.

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

result[id] = INIT;

在循环的每次迭代中为完全相同的对象分配引用,因此它们都指向同一个对象,并且都具有相同的属性(因为它们都是相同的对象).因此,任何进一步的更改result[id]实际上只是对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);

对于旧版浏览器,这里有一个polyfill Object.assign():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

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

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有