簡體   English   中英

JavaScript對象分配的奇怪行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM