我在原型中保存了一个属性_data
,作为所有已创建对象的定义。
function A() {}
A.prototype._data = [];
现在,从A
创建的所有对象都具有属性_data
。
我想要原型继承,原型的_data
将具有来自原型链中所有原型的_data
值。
不知道直接的方式,在这个例子中我使用了一个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
的对象aa
和值b
的对象bb
时,b.get()
会返回[aa, bb]
。稍后如果原型_data
的{{1}}将使用A
进行扩展,则函数aaaa
将返回b.get()
。
[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
引用父原型?
以下是演示:http://jsfiddle.net/j9fKP/
所有这些的原因是ORM库中方案的字段定义,其中允许方案的继承。子计划必须包含来自父计划的所有字段。
答案 0 :(得分:1)
我想要原型继承,原型的
_data
将具有来自原型链中所有原型的_data
值。
这是另一回事。 “原型继承”意味着如果当前对象上有_data
属性,它将不会在链中进一步查看。此外,它似乎是一种issue with nested objects,虽然我不确定你真正想要的是什么。但是,如果你真的想要连接它们,那么让一个数组对象继承另一个数组几乎没有意义。
所以我觉得你的吸气得很好。
如何实现这一目标是一种很好的(标准)方式吗?我的意思是使用构造函数更正Object.create和引用父原型与constructor.prototype
构造函数更正很好,但是actually quite useless(特别是如果你期望符合标准的Object.create
)。
但是,在this.__proto__.constructor.prototype
中,.__proto__
或.constructor.prototype
都是多余的。由于两者都是非标准的或需要构造函数更正,因此您应该使用标准Object.getPrototypeOf()
function来获取原型对象。
使用以下非常通用的解决方案,您可以任意深入地嵌套继承(A.proto,B-proto,B-instance,...)。从A.prototype
继承的所有内容都将使用add
方法将_data
添加到当前对象,并使用get
方法遍历原型链并收集所有_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]
答案 1 :(得分:1)
function A() {}
A.prototype._data = [];
A.prototype.add = function(rec) {
this._data.push(rec);
}
A.prototype.get = function() {
return this._data;
}
function B() {}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});
B.prototype._data = [];
B.prototype.get = function() {
return A.prototype._data.concat(this._data);
}
a.add('aa');
b.add('bb');
console.log(b.get()); // [aa, bb]
a.add('aaaa');
console.log(b.get()); // [aa, aaaa, bb]
答案 2 :(得分:1)
我想我对你现在想做什么有了更好的理解,所以我删除了我之前的答案并发布了这个答案。
以下是我认为我会这样做的原因(但有一点需要注意,我不能确定更好的理解,完全不同的方法会更好):< / p>
function A() {}
A.prototype._Adata = [];
A.prototype.add = function(rec) {
this._Adata.push(rec);
};
A.prototype.get = function() {
return this._Adata;
};
function B() {}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});
B.prototype._Bdata = [];
B.prototype.add = function(rec) {
this._Bdata.push(rec);
};
B.prototype.get = function() {
return this._Adata.concat(this._Bdata);
// Or: return A.prototype.get.call(this).concat(this._Bdata);
};
var a = new A();
var 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]
这样,B
并没有深入到A
的内部。