Javascript 如何使用继承的方法更改继承的数组?

Javascript 如何使用继承的方法更改继承的数组?,javascript,arrays,inheritance,Javascript,Arrays,Inheritance,我想要一个继承数组属性的对象和一个向继承的数组添加元素的方法。但是,继承的方法yChange()会更改原型数组,而不是继承的数组。解释为什么会发生不希望发生的行为。但却不知道如何获得想要的行为 var parent = { x: 0, y: [], xChange: function () {this.x += 1}, yChange: function () {this.y.push(1)} }; var child = Object.create(paren

我想要一个继承数组属性的对象和一个向继承的数组添加元素的方法。但是,继承的方法
yChange()
会更改原型数组,而不是继承的数组。解释为什么会发生不希望发生的行为。但却不知道如何获得想要的行为

var parent = {
    x: 0,
    y: [],
    xChange: function () {this.x += 1},
    yChange: function () {this.y.push(1)}
};

var child = Object.create(parent);
child.xChange();
child.yChange();

console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // 0 [1]
期望的:

console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // 0 []
但是,继承的方法yChange()会更改原型数组,而不是继承的数组

“继承”数组和“原型”数组之间没有区别。他们是同一个人

您必须为
子项提供自己的数组:

var child = Object.create(parent);
child.y = [];


那么,我不能像继承数字一样继承一个“own”数组?问题是如何使用继承的数组

继承的一切都不是孩子“拥有”的。偶数。不同之处在于数字是不可变的,因此问题并不明显

仔细看看这里有什么:

this.x += 1
您正在
this.x
分配一个新值。这将创建
子.x
,而不是修改
父.x

让我们看看

this.y.push(1);
您在这里没有分配任何内容。您正在阅读
this.y
,它解析为
parent.y
,您正在变异数组对象本身

现在是否更清楚了为什么必须
child.y
child.y=[];
)分配一个新数组?赋值是指给孩子自己的数据副本

数字和数组大小写的区别在于,数字是不可变的,数组是可变的。数字的不变性迫使您创建一个新的数字并分配它

对于可变值,情况并非如此。如果不希望共享该值,则必须显式创建该值的副本(这就是
child.y=[];
基本上正在做的事情)

但是,继承的方法yChange()会更改原型数组,而不是继承的数组

“继承”数组和“原型”数组之间没有区别。他们是同一个人

您必须为
子项提供自己的数组:

var child = Object.create(parent);
child.y = [];


那么,我不能像继承数字一样继承一个“own”数组?问题是如何使用继承的数组

继承的一切都不是孩子“拥有”的。偶数。不同之处在于数字是不可变的,因此问题并不明显

仔细看看这里有什么:

this.x += 1
您正在
this.x
分配一个新值。这将创建
子.x
,而不是修改
父.x

让我们看看

this.y.push(1);
您在这里没有分配任何内容。您正在阅读
this.y
,它解析为
parent.y
,您正在变异数组对象本身

现在是否更清楚了为什么必须
child.y
child.y=[];
)分配一个新数组?赋值是指给孩子自己的数据副本

数字和数组大小写的区别在于,数字是不可变的,数组是可变的。数字的不变性迫使您创建一个新的数字并分配它


对于可变值,情况并非如此。如果不希望共享该值,则必须显式创建该值的副本(这就是
child.y=[];
的基本工作)。

Felix关于更改child.y所需的赋值是正确的。在您的示例中,您可以先检查内存地址是否相同,然后为新实例分配一个新的地址(如果它们匹配)。像这样:

var parent = {
    x: 0,
    y: [],
    xChange: function () {this.x += 1},
    yChange: function () {
        if (this.y == Object.getPrototypeOf(this).y)
            this.y = new Array()
        this.y.push(1)
    }
};

var child = Object.create(parent);
child.xChange();
child.yChange();

console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // []

Felix说的对,改变child.y的任务是必要的。在您的示例中,您可以先检查内存地址是否相同,然后为新实例分配一个新的地址(如果它们匹配)。像这样:

var parent = {
    x: 0,
    y: [],
    xChange: function () {this.x += 1},
    yChange: function () {
        if (this.y == Object.getPrototypeOf(this).y)
            this.y = new Array()
        this.y.push(1)
    }
};

var child = Object.create(parent);
child.xChange();
child.yChange();

console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // []

有什么原因你不能使用构造函数吗?我可以,但我想使用对象文字和
object.create()
。有什么原因你不能使用构造函数吗?我可以,但我想使用对象文字和
object.create()
。所以,我不能像继承数字一样继承“自己的”数组?问题是如何使用继承的数组。继承的所有内容都不是子对象的“所有”。偶数。不同之处在于数字是不可变的,因此问题并不明显。你可能想再次阅读链接的问题,我觉得你还没有真正理解原因(哈,我回答了那个问题……很有趣,也许我没有做得这么好)。是的,我的问题是最明确的,“如何?”@Dave:然后答案是:“你不能”。你不能神奇地让一个数组(
parent.y
)像两个一样。那么,我不能像继承数字一样继承一个“自己的”数组?问题是如何使用继承的数组。继承的所有内容都不是子对象的“所有”。偶数。不同之处在于数字是不可变的,因此问题并不明显。你可能想再次阅读链接的问题,我觉得你还没有真正理解原因(哈,我回答了那个问题……很有趣,也许我没有做得这么好)。是的,我的问题是最明确的,“如何?”@Dave:然后答案是:“你不能”。您不能神奇地使单个数组(
parent.y
)像两个一样。如果希望能够执行
parent.yChange
,则该条件应扩展为
this!==父级&…
我想我只需要使用构造函数。谢谢@JpajiRajnish。写完这篇文章后,我意识到如果你想从
孩子
继承,你会遇到问题。要解决这个问题,您可以显式地调用实例的原型,而不是
parent
,并检查该实例的内存地址。(答案已编辑)如果希望能够执行
parent.yChange
,则条件应为