del*_*sin 2 javascript loops object node.js assign
我是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);
Run Code Online (Sandbox Code Playgroud)
RESULT_0:
{ A: { name: 'A' }, B: { name: 'B' }, C: { name: 'C' } }
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
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' } }
Run Code Online (Sandbox Code Playgroud)
我能理解为什么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' } }
Run Code Online (Sandbox Code Playgroud)
code_0和code_1之间有什么区别?为什么code_1会给出result_1?
编辑:*添加与问题相关的标签.*更改标题.(过去的标题是for/in循环)
在Javascript中通过引用(而不是通过复制)分配对象.这是第一次在Javascript中加速时混淆和学习的常见问题.
在您的code_1块中,这行代码:
result[id] = INIT;
Run Code Online (Sandbox Code Playgroud)
在循环的每次迭代中为完全相同的对象分配引用,因此它们都指向同一个对象,并且都具有相同的属性(因为它们都是相同的对象).因此,任何进一步的更改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);
Run Code Online (Sandbox Code Playgroud)
对于旧版浏览器,这里有一个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
Run Code Online (Sandbox Code Playgroud)
您可以看到所有三个变量都显示相同的值,因为它们都指向完全相同的对象,因此通过三个变量中的任何一个修改对象会产生完全相同的变化.