繁体   English   中英

在 javascript 中修改继承数组而不更改其父数组的最佳方法是什么

[英]What's the best way to modify an inherited array in javascript without changing its parent

我想制作一个继承自其他 object 的 object。 在构造后代时,我想在不更改父对象的情况下将一些项目推送到继承的数组中。

假设我有一个称为篮子的 object:

function Basket(){
}

然后我像这样填充它:

Basket.prototype {
    “price”: 5,
    “contents” : [“apple”, “orange”, “grape”]
}

现在我想扩展它。 我想添加一些属性并更改一些。 我这样做了:

function BigBasket(){
    this.price = 6; // change a property. This goes well, when an instance is created, price is still 5 in prototype and also in instances of Basket and it is 6 in the instance that is created from this descendant.
    this.greetingcard = “Congratulations” // add a property. Goes well

现在我想在内容属性中添加一个项目,但只在后代实例中。

这出错了:

    this.contents.push(“banana”); 

似乎 this.contents 包含对原型数组的引用,因此当将香蕉推送到它时,意味着 Bigbasket 和 Basket 的实例也会在其内容中获取香蕉。 因此,我首先制作了 Basket.contents (父内容)的副本,如下所示:

    this.contents = Object.getPrototypeOf(this).contents.slice(); // seems __proto__ is deprecated, so using getPrototypeOf here and then pushed the banana:
    this.contents.push(‘banana’);
}

这似乎有效,但这是正确的方法吗? 我知道数组也是 object,所以我尝试了这个:

    this.contents = Object.create(Basket.prototype.contents);
    this.contents.push('banana');

这也有效,似乎是一种更通用的方式。 此外,在 Chrome 中,最后推送的项目只是后代的属性,而数组项目的 rest 是原型的属性。 对我来说似乎很优雅。

不过,这对我来说看起来有点笨拙。 我做错了吗? 试图找出但在扩展对象中找不到关于数组主题的任何内容。 有没有一种方法可以使所有属性在实例化时都被复制而不被引用?

谢谢!

你可以尝试这样的事情:

  • 不要将pricecontent放在原型上,而是将它们作为Basket的属性。
  • 继承BigBasket并将其原型设置为Basket的实例。 这将使您可以访问篮子的属性。
  • BigBasket中定义一个私有变量content ,其工作是维护孩子的内容。
  • 添加一个设置器 function 来改变这个变量

    • addContent :向孩子的内容添加新值
    • removeContentByIndex :根据索引删除值。
    • getContent :这将返回content的副本以消除副作用。 这也将允许您对内容进行自定义定义。 在这种情况下,它自己的内容+父母的内容

    这将允许您定义 API 以与内容通信,还允许您创建公开的限制数据。 暴露一切可能会导致问题。 暴露需要的东西总是更好的。

注意:在原型上放置对象可能会导致问题,因为对象会产生副作用。 您应该只使用 Parent 的值作为默认值。

 function Basket() { this.price = 5; this.contents = ["apple", "orange", "grape"] } function BigBasket() { const content = []; this.price = 6; this.greetingcard = "Congratulations"; this.addContent = function(value) { content.push(value); } this.removeContentByIndex = function(index) { content.splice(index, 1); } this.getContents = function() { return [].concat(this.__proto__.contents, content); } } BigBasket.prototype = new Basket(); const bb1 = new BigBasket(); const bb2 = new BigBasket(); bb1.addContent('banana'); console.log(bb1.getContents(), bb2.getContents())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM