问题描述
我在原型中保存了一个属性 _data
作为所有已创建对象的定义。
I have saved a property _data
in prototype as a definition for all created objects.
function A() {}
A.prototype._data = [];
现在从 A
创建的所有对象都有属性 _data
。
Now all objects created from A
have property _data
.
我想原型继承,其中 _data $ c $原型链中所有原型的原型都将具有
_data
值。
I'd like prototype inheritance, where _data
of prototype will have _data
values from all prototypes in prototype chain.
不知道直接方式,在这个例子中,我使用getter get()
。
Don't know direct way, in this example I use a getter get()
.
function A() {}
A.prototype._data = [];
A.prototype.add = function(rec) {
this.__proto__._data.push(rec);
}
A.prototype.get = function() {
if(typeof this.__proto__.constructor.prototype.get == 'function')
{
return this.__proto__.constructor.prototype.get().concat(this.__proto__._data);
}
else
{
return this.__proto__._data || [];
}
}
function B() {}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});
B.prototype._data = [];
当我使用值 a 时code> aa 和对象 b
,其值 bb
, b.get()
返回 [aa,bb]
。稍后如果 _data
原型 A
将使用 aaaa
,function b.get()
返回 [aa,aaaa,bb]
。
When I create object a
with values aa
and object b
with value bb
, b.get()
returns [aa, bb]
. And later if _data
of prototype A
will be extended with aaaa
, function b.get()
returns [aa, aaaa, bb]
.
var a = new A(), b = new B();
a.add('aa');
b.add('bb');
console.log(b.get()); // [aa, bb]
a.add('aaaa');
console.log(b.get()); // [aa, aaaa, bb]
// EDITED - _data in A prototype shoud be without B
console.log(a.get()); // [aa, aaaa]
如何实现这一目标是一种很好的(标准)方式吗?我的意思是在 Object.create
时使用构造函数修正,并使用 constructor.prototype
引用父原型?
Is it a good (standard) way how to achieve this? I mean using constructor correction while Object.create
and reference parent prototype with constructor.prototype
?
这是一个演示:
所有这些的原因是ORM库中scheme的字段定义,其中允许继承方案。子方案必须包含来自父方案的所有字段。
Reason for all of this is field definition for scheme in ORM library, where inheritance of schemes is allowed. Child scheme has to have all fields from parent scheme.
推荐答案
这是另一回事。 原型继承意味着如果当前对象上有 _data
属性,它将不会在链中进一步查看。此外,它似乎是一种,虽然我不确定你真正想要什么。但是,如果你真的想要连接它们,那么让一个数组对象继承另一个数组几乎没有意义。
That's a different thing. "Prototype inheritance" means that if there's a _data
property on the current object, it won't go looking further in the chain. Also, it seems to be a kind of issue with nested objects, though I'm not sure what you really want. However, it hardly will make sense to let an array object inherit from another array, if you actually want to concatenate them.
所以我认为你的getter非常好。
So I think your getter is really fine.
构造函数更正很好,但是(特别是如果你期望符合标准 Object.create
)。
Constructor correction is nice, but actually quite useless (especially if you expect a standard-conform Object.create
).
然而,在中这个.__ proto __。constructor.prototype
.__ proto __
或 .constructor.prototype
是多余的。由于两者都是非标准的或需要构造函数更正,因此您应该使用标准来获取原型对象。
However, in this.__proto__.constructor.prototype
either the .__proto__
or the .constructor.prototype
is redundant. Since both are either nonstandard or require constructor correction, you should use the standard Object.getPrototypeOf()
function to get your prototype object.
使用以下非常通用的解决方案,您可以任意深入地嵌套继承(A.proto,B-proto,B-instance,...)。继承自 A.prototype
的所有内容都将包含 add
方法,该方法会添加 _data
到当前对象,以及 get
方法遍历原型链并收集所有 _data
:
With the following very generic solution, you can nest the inheritance (A.proto, B-proto, B-instance, …) arbitrarily deep. Everything inheriting from A.prototype
will have an add
method which adds _data
to the current object, and a get
method that traverses the prototype chain and collects all _data
:
function A() {
// this._data = []; // why not?
}
A.prototype._data = []; // not even explicitly needed
A.prototype.add = function(rec) {
if (! this.hasOwnProperty("_data")) // add it to _this_ object
this._data = [];
this._data.push(rec);
}
A.prototype.addToAllInstances = function(rec) {
Object.getPrototypeOf(this).add(rec);
}
A.prototype.get = function() {
var proto = Object.getPrototypeOf(this);
var base = typeof proto.get == 'function' ? proto.get() : [];
// maybe better:
// var base = typeof proto.get == 'function' && Array.isArray(base = proto.get()) ? base : [];
if (this.hasOwnProperty("_data"))
return base.concat(this._data); // always get a copy
else
return base;
}
function B() {
A.call(this);
}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});
B.prototype._data = []; // not even explicitly needed
用法示例:
var a = new A();
var b = new B();
a.add('ai');
a.get(); // [ai]
a.addToAllInstances('ap'); // === A.prototype.add('ap');
a.get(); // [ap, ai]
new A().get(); // [ap]
b.get(); // [ap]
b.prototype.get(); // [ap]
b.add('bi');
b.get(); // [ap, bi]
a.addToAllInstances('aap');
b.addToAllInstances('bp');
b.get(); // [ap, aap, bp, bi]
这篇关于javascript原型继承 - 共享属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!