【发布时间】:2020-02-20 18:09:37
【问题描述】:
我想创建一个继承自其他对象的对象。在构造后代时,我想在不更改父对象的情况下将一些项目推送到继承的数组中。
假设我有一个叫做篮子的对象:
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’);
}
这似乎有效,但这是正确的方法吗?我知道数组也是一个对象,所以我尝试了这个:
this.contents = Object.create(Basket.prototype.contents);
this.contents.push('banana');
这也有效,似乎是一种更通用的方式。此外,在 Chrome 中,最后推送的项目只是后代的属性,而其余的数组项目是原型的属性。对我来说似乎很优雅。
不过,这对我来说看起来有点笨拙。我做错了吗?试图找出但在扩展对象中找不到关于数组主题的任何内容。有没有办法在实例化时复制所有属性而不是引用的后代?
谢谢!
【问题讨论】:
-
一个技巧开始。原型中永远不会有对象。原型最适合不太可能改变的静态值。
-
当你访问
this.contents时,它会直接在对象上查找属性。没有找到。然后,它将在其[[Prototype]]中查找该属性。这里是Basket.prototype.contents。因此,它将推送到该数组。在第二种情况下,有一个 owncontents属性,因此它永远不会在[[Prototype]]中查找
标签: javascript arrays object inheritance properties