6

_data在原型中保存了一个属性作为所有创建对象的定义。

 function A() {}
 A.prototype._data = [];

现在创建的所有对象A都具有 property _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对象时,返回。稍后如果原型将被扩展,函数返回。bbbb.get()[aa, bb]_dataAaaaab.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并使用 ? 引用父原型constructor.prototype

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

所有这一切的原因是 ORM 库中方案的字段定义,其中允许方案的继承。子方案必须具有父方案的所有字段。

4

3 回答 3

1

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

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

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

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

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

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.

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

Example usage:

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]
于 2013-03-16T13:57:08.757 回答
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]

Fiddle

于 2013-03-16T14:08:00.017 回答
1

I think I have a better understanding of what you want to do now, so I've deleted my earlier answer and am posting this one.

Here's how I think I'd do it (with the caveat that I'm not at all sure that with an even better understanding, a completely different approach wouldn't be better):

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]

Fiddle

That way, B isn't reaching too deeply into A's internals.

于 2013-03-16T14:17:12.870 回答