javascript原型继承 - 共享属性

opi*_*pio 6 javascript inheritance prototype

我已将_data原型中的属性保存为所有已创建对象的定义.

 function A() {}
 A.prototype._data = [];
Run Code Online (Sandbox Code Playgroud)

现在所有创建的对象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 = [];
Run Code Online (Sandbox Code Playgroud)

当我a使用值创建对象和带有值的aa对象bbb,b.get()返回[aa, bb].后来如果_data将原型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]
Run Code Online (Sandbox Code Playgroud)

如何实现这一目标是一种很好的(标准)方式吗?我的意思是使用构造函数校正,Object.create并参考父原型与constructor.prototype

这是一个演示:http://jsfiddle.net/j9fKP/

所有这些的原因是ORM库中方案的字段定义,其中允许方案的继承.子计划必须包含来自父计划的所有字段.

Ber*_*rgi 1

\n

我想要原型继承,其中_data原型将具有_data原型链中所有原型的值。

\n
\n\n

那是不同的事情。“原型继承”意味着如果当前对象有_data属性,它就不会在链中进一步查找。另外,这似乎是嵌套对象的一种问题,尽管我不确定你真正想要什么。但是,如果您确实想要连接数组对象,那么让一个数组对象从另一个数组继承几乎没有意义。

\n\n

所以我认为你的吸气剂真的很好。

\n\n
\n

这是实现这一目标的好(标准)方法吗?我的意思是在 Object.create 时使用构造函数校正并使用 constructor.prototype 引用父原型

\n
\n\n

构造函数修正很好,但实际上毫无用处(特别是如果您期望符合标准Object.create)。

\n\n

然而,this.__proto__.constructor.prototype无论是 the.__proto__还是 the.constructor.prototype都是多余的。由于两者要么是非标准的,要么需要构造函数更正,因此您应该使用标准Object.getPrototypeOf()函数来获取原型对象。

\n\n

使用以下非常通用的解决方案,您可以将继承(A.proto、B-proto、B-instance、\xe2\x80\xa6)嵌套任意深度。继承自的所有内容A.prototype都会有一个添加到当前对象的add方法,以及一个遍历原型链并收集所有对象的方法:_dataget_data

\n\n
function A() {\n    // this._data = []; // why not?\n}\nA.prototype._data = []; // not even explicitly needed\nA.prototype.add = function(rec) {\n    if (! this.hasOwnProperty("_data")) // add it to _this_ object\n        this._data = [];\n    this._data.push(rec);\n}\nA.prototype.addToAllInstances = function(rec) {\n    Object.getPrototypeOf(this).add(rec);\n}\nA.prototype.get = function() {\n    var proto = Object.getPrototypeOf(this);\n    var base = typeof proto.get == \'function\' ? proto.get() : [];\n    // maybe better:\n    // var base = typeof proto.get == \'function\' && Array.isArray(base = proto.get()) ? base : [];\n    if (this.hasOwnProperty("_data"))\n        return base.concat(this._data); // always get a copy\n    else\n        return base;\n}\n\nfunction B() {\n    A.call(this);\n}\nB.prototype = Object.create(A.prototype, { constructor: { value: B }});\nB.prototype._data = []; // not even explicitly needed\n
Run Code Online (Sandbox Code Playgroud)\n\n

用法示例:

\n\n
var a = new A();\nvar b = new B();\n\na.add(\'ai\');\na.get(); // [ai]\n\na.addToAllInstances(\'ap\'); // === A.prototype.add(\'ap\');\na.get(); // [ap, ai]\nnew A().get(); // [ap]\nb.get(); // [ap]\nb.prototype.get(); // [ap]\n\nb.add(\'bi\');\nb.get(); // [ap, bi]\n\na.addToAllInstances(\'aap\');\nb.addToAllInstances(\'bp\');\nb.get(); // [ap, aap, bp, bi]\n
Run Code Online (Sandbox Code Playgroud)\n