本文介绍了javascript原型继承 - 共享属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在原型中保存了一个属性 _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 _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原型继承 - 共享属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 05:40