在这段代码中,我使用传播运算符将obj
复制到copiedObj
中。然后将checked
属性值修改为false
。但是,当我console.log(obj.checked[0])
时,它返回false而不是true。并且似乎checked
中的copiedObj
值也更改了原始属性值。这是为什么?
const obj = [{id: 1, checked: true}];
const copiedObj = [...obj];
copiedObj.checked[0] = false;
console.log(obj.checked[0]);
答案 0 :(得分:5)
System.InvalidOperationException - A method was called at an unexpected time.
和obj
是数组,而不是普通对象。更改copiedObj
的状态(通过向其添加copiedObj
属性)不会更改checked
的状态,因为它们是独立的数组。
但是,两个数组都包含对相同对象(上面带有obj
的对象)的引用。因此,如果您这样做:
cheecked
这将更改该对象的状态,您将看到在checkedObj[0].checked = true;
或obj[0]
上查找该对象。
如果要进行深层复制,以便具有单独的数组和独立的对象,请参见this question's answers。
由于我99%确信您的意思是checkedObj[0]
,所以我将解释这段代码中发生的事情:
checkedObj[0].checked = true
逐步:
之后
// Creates an array containing an object
const obj = [{id: 1, checked: true}];
// Creates a new array that contains the *same* object (NOT a *copy* of it)
const copiedObj = [...obj];
// Sets `checked` on that one object that is in both arrays
copiedObj[0].checked = false;
// Looks at the `checked` property on that one object that is in both arrays
console.log(obj[0].checked);
在内存中您有类似的东西
+−−−−−−−−−−−−−+ obj:Ref44329−−−−−>| (array) | +−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | 0: Ref82445 |−−−>| (object) | +−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | id: 1 | | checked: true | +−−−−−−−−−−−−−−−+
那么当你做
// Creates an array containing an object
const obj = [{id: 1, checked: true}];
你有类似的东西:
+−−−−−−−−−−−−−+ obj:Ref44329−−−−−−−−−−>| (array) | +−−−−−−−−−−−−−+ | 0: Ref82445 |−−+ +−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−−+ +−−>| (object) | +−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+ checkedObj:Ref12987−−−>| (array) | | | id: 1 | +−−−−−−−−−−−−−+ | | checked: true | | 0: Ref82445 |−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
那么当你做
// Creates a new array that contains the *same* object (NOT a *copy* of it)
const copiedObj = [...obj];
它更改两个数组都指向的对象
+−−−−−−−−−−−−−+ obj:Ref44329−−−−−−−−−−>| (array) | +−−−−−−−−−−−−−+ | 0: Ref82445 |−−+ +−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−−+ +−−>| (object) | +−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+ checkedObj:Ref12987−−−>| (array) | | | id: 1 | +−−−−−−−−−−−−−+ | | checked: false | | 0: Ref82445 |−−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−+
...因此,无论您通过哪个数组查看它,查找它都会得到// Sets `checked` on that one object that is in both arrays
copiedObj[0].checked = false;
。
答案 1 :(得分:1)
obj
是对象的数组,当您这样做时:
const copiedObj = [...obj];
您创建了一个新数组,但是在该数组中,您仍将引用obj
之所以发生这种情况,是因为您有两个级别:数组->对象,但是散布运算符仅适用于第一级别(数组)
答案 2 :(得分:1)
这是因为,当您由散布运算符创建copiedObj
时,仍在引用最初在内存中创建的对象。
为了解决此问题,以便获得预期的行为,还创建对象内部所有属性的另一个浅表副本。
p.s。我修改了copiedObj[0].checked = false; console.log(obj[0].checked)
,因为我认为您正在尝试选择创建的数组中的第一个元素。
const obj = [{id: 1, checked: true}];
const copiedObj = [Object.assign({}, obj[0])];
copiedObj[0].checked = false;
console.log(obj[0].checked)
//returns true