[英]Javascript object assignment's strange behavior
我是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循環)
對象是通過Javascript中的引用(而不是副本)分配的。 當初次使用Javascript時,這是令人困惑和學習的共同點。
在您的code_1
塊中,以下代碼行:
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()
: https : //developer.mozilla.org/zh-CN/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
您會看到所有三個變量都顯示相同的值,因為它們都指向完全相同的對象,因此通過三個變量中的任何一個修改對象都會產生完全相同的更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.