2013-03-16 12 views
6

मैंने सभी निर्मित वस्तुओं के लिए परिभाषा के रूप में प्रोटोटाइप में _data संपत्ति सहेजी है।जावास्क्रिप्ट प्रोटोटाइप विरासत - साझा संपत्ति

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

अब A से बनाए गए सभी वस्तुओं संपत्ति _data है।

मुझे प्रोटोटाइप विरासत चाहिए, जहां प्रोटोटाइप के _data प्रोटोटाइप श्रृंखला में सभी प्रोटोटाइपों से _data मान होंगे।

प्रत्यक्ष तरीके से नहीं पता, इस उदाहरण में मैं एक गेटर 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 = []; 

जब मैं मान aa के साथ वस्तु a बना सकते हैं और मूल्य bb साथ b वस्तु, b.get() रिटर्न [aa, bb]। और बाद में _data प्रोटोटाइप Aaaaa के साथ बढ़ाया जाएगा, फ़ंक्शन 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 और constructor.prototype के साथ संदर्भ पैरेंट प्रोटोटाइप के दौरान कन्स्ट्रक्टर सुधार का उपयोग करना? इस सब के लिए http://jsfiddle.net/j9fKP/

कारण ORM पुस्तकालय है, जहां योजनाओं की विरासत की अनुमति दी है में इस योजना के लिए क्षेत्र परिभाषा है:

यहाँ एक डेमो है। बाल योजना में सभी योजनाएं मूल योजना से होनी चाहिए।

+0

संभावित डुप्लिकेट [जावास्क्रिप्ट ऑब्जेक्ट सदस्यों जो सरणी के रूप में प्रोटोटाइप किए जाते हैं, सभी वर्ग उदाहरणों द्वारा साझा किए जाते हैं] (http://stackoverflow.com/questions/4425318/javascript-object-members-that-are-prototyped-as-arrays -बेक-साझा-द्वारा-सब-क्लै) – Bergi

उत्तर

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 का उपयोग करना चाहिए।

निम्नलिखित बहुत सामान्य समाधान के साथ, आप विरासत (ए।प्रोटो, बी-प्रोटो, बी-इंस्टेंस, ...) मनमाने ढंग से गहरा।

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] 
+0

वास्तव में अच्छा कोड! getPrototypeOf के साथ और उदाहरण _डेटा संपत्ति भी भूल गया। उत्कृष्ट स्पष्टीकरण और उदाहरण के लिए बहुत बहुत धन्यवाद। वास्तव में मुझे क्या चाहिए। – opio

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] 
सब कुछ A.prototype से इनहेरिट एक add विधि है जो वर्तमान वस्तु को _data कहते हैं, और एक get विधि है कि प्रोटोटाइप श्रृंखला को पार करता है और सभी _data एकत्र करता होगा

Fiddle

+0

मुझे हाल ही में संपादित किए गए बुरे प्रश्न के लिए खेद है, a.get() केवल [aa, aaaa] वापस आना चाहिए। धन्यवाद – opio

+0

मुझे पता है, और यही मेरा कोड करता है। – zeroflagL

1

मुझे लगता है कि मुझे बेहतर समझ है जो आप अभी करना चाहते हैं उसके बारे में, इसलिए मैंने अपना पिछला उत्तर हटा दिया है और इसे पोस्ट कर रहा हूं।

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

इस तरह, BA के internals में भी गहराई से नहीं पहुँच रहा।

+0

'_Adata'" एक आंतरिक "नहीं है? आप ए ('im') का उपयोग कर सकते हैं (और imo चाहिए)। – Bergi

+0

@ बर्गि: हाँ, मुझे लगता है कि आप तर्क दे सकते हैं कि यह है। मेरे लिए, इन बिंदुओं का पूरा बिंदु उस जानकारी को साझा करना है, इसलिए मैं उन्हें "आंतरिक" नहीं मानता, और 'ए' के ​​'ए' के संस्करण को कॉल करना एक सहायक पुस्तकालय के बिना दर्द है। लेकिन मैंने इसे एक विकल्प के रूप में जोड़ा है। –

संबंधित मुद्दे