不仅在parent-> child之间,而且在原型的所有child之间都继承?

问题描述

我认为对象的继承仅在父级到子级之间起作用,但是我的代码显示了“兄弟姐妹”之间的奇怪继承。
所以我想知道为什么数组 testObj 的所有对象(是 myObj 的子对象)都具有相同的数据。
我的代码仅用于学习,没有特定目的。

// my prototype-obj
const myObj = {
    myArray: [],declaration: ""
}

// my array of objects
let testObj = [];

// fill my object
for (i=0; i < 4; i++) {
    testObj[i] = Object.create(myObj);
    testObj[i].myArray.push("content of array " + i);        
}

// print my data
testObj.forEach((eleA,idxA) => {
    console.log("\nobj number "+idxA);        
    eleA.myArray.forEach((eleB,idxB) => {
        console.log(eleB);
    });
});
console output:

obj number 0
content of array 0
content of array 1
content of array 2

obj number 1
content of array 0
content of array 1
content of array 2

obj number 2
content of array 0
content of array 1
content of array 2

https://jsfiddle.net/tkzw2fn8/

解决方法

您有一个对象(A),其属性之一具有一个数组作为值。

您使用Object.create以A为原型创建一些新对象(AA,AB,AC)。

对于AA,AB和AC中的每一个,您都访问myArray属性,并使用push对其进行操作。

由于AA,AB和AC没有其拥有 myArray属性,因此当您访问它时,将遵循原型链,您将获得来自A的myArray


简而言之:原型继承不会为继承的值创建深层次的副本

,

好吧,这将需要很长的答案,但对我来说几乎是裸露的, 当您通过原型链继承一个数组“ myArray”时,您会得到一个引用,这就是为什么即使您执行类似操作

console.log(myObj.myArray);

最后,您将看到它等于您拥有的其余对象,现在,如果您也尝试在for循环中修改声明,那么真正令人困惑的部分就出现了,

testObj[i].declaration="test"+i;

您会注意到一个不同的行为,那就是因为JS执行了称为“ Shadowing”属性的操作,但这仅适用于原始类型,这就是为什么在更改数组时,它也随处更改(也称为“通过引用继承”),以及类似“声明”不是。

因此,为了获得每个对象的唯一数组,必须重新创建该数组“如果且仅当原型链中具有该数组,因为如果没有,它将被引用继承”,以进行更改参考。

希望这可以消除一些困惑