简体   繁体   English

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

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

I want to make an object that inherits from an other object.我想制作一个继承自其他 object 的 object。 In constructing the descendant, i want to push some items to an inherited array without changing the parentobject.在构造后代时,我想在不更改父对象的情况下将一些项目推送到继承的数组中。

Say I have an object called basket:假设我有一个称为篮子的 object:

function Basket(){
}

Then i fill it like this:然后我像这样填充它:

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

Now i want to extend this.现在我想扩展它。 I want to add some properties and change some.我想添加一些属性并更改一些。 I did this:我这样做了:

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

Now i want to add an item to the contents-property but only in the descendant instances.现在我想在内容属性中添加一个项目,但只在后代实例中。

This goes wrong:这出错了:

    this.contents.push(“banana”); 

It seems this.contents contains a reference to the array of the prototype so when pushing a banana to it, means that instances of both Bigbasket and Basket get a banana in their contents as well.似乎 this.contents 包含对原型数组的引用,因此当将香蕉推送到它时,意味着 Bigbasket 和 Basket 的实例也会在其内容中获取香蕉。 Therefore i first made a copy of the Basket.contents (the parent contents) like this:因此,我首先制作了 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’);
}

This seems to be working, but is this the right way?这似乎有效,但这是正确的方法吗? I know array is an object as well, so i tried this:我知道数组也是 object,所以我尝试了这个:

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

This works too and seems a more generic way.这也有效,似乎是一种更通用的方式。 Furthermore in Chrome the item that was pushed last was a property of only the descendant while the rest of the array-items were properties of the prototype.此外,在 Chrome 中,最后推送的项目只是后代的属性,而数组项目的 rest 是原型的属性。 Seems elegant to me.对我来说似乎很优雅。

Still, this looks a bit clumsy to me.不过,这对我来说看起来有点笨拙。 Am i doing this all wrong?我做错了吗? Tried to find out but couldn't find anything on the topic of array's in extending objects.试图找出但在扩展对象中找不到关于数组主题的任何内容。 Is there a way of making descendants where all properties are copied and not referenced when instanciated?有没有一种方法可以使所有属性在实例化时都被复制而不被引用?

Thanks!谢谢!

You can try something like this:你可以尝试这样的事情:

  • Instead of putting price and content on prototype, make them as properties of Basket .不要将pricecontent放在原型上,而是将它们作为Basket的属性。
  • Inherit BigBasket and set its prototype as instance of Basket .继承BigBasket并将其原型设置为Basket的实例。 This will give you access to properties of Basket.这将使您可以访问篮子的属性。
  • Define a private variable content in BigBasket whose job will be to maintain the child's content.BigBasket中定义一个私有变量content ,其工作是维护孩子的内容。
  • Add a setter function to mutate this variable添加一个设置器 function 来改变这个变量

    • addContent : Add new values to child's content addContent :向孩子的内容添加新值
    • removeContentByIndex : to remove value based on index. removeContentByIndex :根据索引删除值。
    • getContent : This will return a copy of content to nullify side effect. getContent :这将返回content的副本以消除副作用。 This will also allow you to have custom definition of content.这也将允许您对内容进行自定义定义。 In this case, its own content + parent's content在这种情况下,它自己的内容+父母的内容

    this will allow you to define an API to communicate with content and also allows you to create a restrict data that is exposed.这将允许您定义 API 以与内容通信,还允许您创建公开的限制数据。 Exposing everything can cause issues.暴露一切可能会导致问题。 Exposing what is required is always better.暴露需要的东西总是更好的。

Note: Having objects on prototype can cause issues as objects will have side effect.注意:在原型上放置对象可能会导致问题,因为对象会产生副作用。 You should use Parent's values as default values only.您应该只使用 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.

相关问题 使用Javascript查找和修改数组中的对象的最佳方法是什么? - What's most optimal way to find and modify object in array with Javascript? 删除 JavaScript 数组中特定字符的最佳方法是什么? - What's the best way to delete specific characters in a JavaScript array? 更改javascript对象数组中的对象属性的最佳方法是什么? - what's the best way to change an object property in a javascript object array? 在javascript中找到两个DOM节点的第一个公共父节点的最佳方法是什么? - What's the best way to find the first common parent of two DOM nodes in javascript? 修改已抓取网页中包含的JavaScript的最佳方法是什么? - What is the best way to modify the JavaScript included in a scraped web page? 什么是部分修改javascript中的锚href的最佳方法 - what is the best way to partially modify anchor href in javascript Javascript:如何在不更改引用的情况下修改数组中的每个元素 - Javascript: How to modify each element in array without changing the reference 调试Javascript / AngularJS的最佳方法是什么? - What's the best way to debug Javascript/AngularJS? 为 OpenTest 学习 JavaScript 的最佳方法是什么 - What's the best way to learn JavaScript for OpenTest 在JavaScript中计算关键字的最佳方法是什么? - What's the best way to count keywords in JavaScript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM