2012-01-04 16 views
6

मैं जावास्क्रिप्ट में किसी फ़ंक्शन में प्रोटोटाइप विरासत को लागू करने का प्रयास कर रहा हूं। यह सब सुंदर सादा है और यहां तक ​​कि Wikipedia's javascript lemma में वर्णित है। यह काम करता है अगर मेरे गुण सरल जावास्क्रिप्ट प्रकार हैं:जावास्क्रिप्ट प्रोटोटाइप विरासत और ऑब्जेक्ट गुण

function Person() { 
    this.age = 0; 
    this.location = { 
     x: 0, 
     y: 0, 
     absolute: false 
    }; 
}; 

function Employee() {}; 

Employee.prototype = new Person(); 
Employee.prototype.celebrate = function() { 
    this.age++; 
} 

var pete = new Employee(); 
pete.age = 5; 
pete.celebrate(); 
var bob = new Employee(); 
bob.celebrate(); 
console.log("bob is " + bob.age + " pete is " + pete.age); 
Employee.prototype = new Person(); साथ

, सभी व्यक्ति के गुण और (नमूने) तरीके कर्मचारी है, जो विरासत के लिए मौलिक है से प्राप्त होती हैं।

यह अपेक्षा के अनुरूप काम करता है: bob is 1 pete is 6

अब मैं पीट स्थान के साथ बेला को शुरू कर (जश्न मनाने के बाद)

pete.celebrate(); 
pete.location.absolute=true; 

प्रदर्शित bob.location.absolute पता चलता है: true, (जो विपरीत सहज है मैंने बॉब के स्थान को स्पर्श नहीं किया है, इसलिए मुझे उम्मीद है कि इसे Person में प्रारंभिक मूल्य घोषित किया जाएगा) और मेरा समाधान बर्बाद कर देगा।

मेरी प्रारंभिक समझ में यह गलत होना चाहिए था। मुझे एहसास है कि मुझे शायद प्रारंभिक व्यक्ति से स्थान वस्तु को क्लोन करना चाहिए, लेकिन मुझे यकीन नहीं है कि यह कहां या कैसे करें। और यदि विरासत के लिए शायद बेहतर तकनीकें हैं?

उत्तर

3

जब आप एक नए कर्मचारी को तत्काल बनाते हैं, तो व्यक्ति के सभी गुणों की प्रतिलिपि बनाई जाती है। चूंकि यह एक उथली प्रतिलिपि है, पेटी और बॉब एक ​​ही स्थान वस्तु साझा करते हैं। आपकी समस्या के लिए, एक बहुत अच्छा समाधान नहीं लगता है। तुम एक ढांचे का उपयोग कर सकते हैं या इस तरह एक हैक कर सकते हैं:

function Employee() { Person.apply(this); }; 

यह इस वस्तु के संदर्भ में व्यक्ति निर्माता कहता है। https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

3

जब इनहेरिट Person निर्माता भागो मत, एक Employee भी एक .location यह Person.prototype में नहीं है क्योंकि न होना चाहिए:

MDC इस बारे में अधिक जानकारी नहीं है।

function createObject(fn){ 
    function f(){} 
    f.prototype = fn.prototype; 
    return new f; 
} 
फिर

:

Employee.prototype = createObject(Person); 

यह बिना साइड इफेक्ट (चल निर्माता) ठीक से प्राप्त कर लेगा।

आप केवल बच्चे निर्माता में माता पिता के निर्माता चलाने होगा:

function Employee() { 
Person.apply(this, arguments); 
} 
+0

नए व्यक्ति() के बजाय createObject (व्यक्ति) का उपयोग करने का उछाल क्या है? यह केवल प्रोटोटाइप संकेत की एक परत जोड़ता है। विरासत के दौरान एक कन्स्ट्रक्टर चलाने से साइड इफेक्ट्स से बचने के लिए – Kosta

+0

@ कोस्टा। कन्स्ट्रक्टर्स में आमतौर पर प्रारंभिक कोड होता है जिसे आप तब तक नहीं चलाना चाहते जब आप कुछ भी तत्काल नहीं कर रहे हों। एक 'नया कर्मचारी' अभी भी व्यक्ति का उदाहरण होगा क्योंकि दोनों व्यक्ति'prototype' और 'f.prototype' एक ही वस्तु को इंगित करते हैं। – Esailija

+0

लेकिन आप अभी भी createObject() (एक बार) में कन्स्ट्रक्टर चला रहे हैं। साथ ही, आप कर्मचारी() में प्रत्येक कन्स्ट्रक्शन में कन्स्ट्रक्टर चला रहे हैं। क्या आप एक उदाहरण दे सकते हैं जहां createObject() उपयोगी है? – Kosta

0

मैं वही समस्या का सामना किया। मैं आंतरिक वस्तु के लिए एक अलग कन्स्ट्रक्टर का उपयोग कर समाप्त हो गया।

function engine(cc, fuel) { 
     this.cc = cc; 
     this.fuel = fuel 
} 

function car(type, model, cc, fuel) { 
     this.type = type; 
     this.model = model; 
     this.engine = new engine(cc, fuel); 
} 


var mycar = new car("sedan", "toyota corolla", 1500, "gas"); 
console.log(mycar.type); 
//sedan 
console.log(mycar.engine.cc); 
//1500 

यदि मेरे पास 'इंजन' या 'कार' रचनाकारों के प्रोटोटाइप पर कोई तरीका था, तो वे अभी भी उपलब्ध होंगे। हालांकि, मैं ओओपी भावना में "इंजन" कक्षा से "कार" कक्षा नहीं प्राप्त कर रहा हूं। मुझे इसकी आवश्यकता नहीं थी। "इंजन" का प्रयोग "कार" के घटक के रूप में किया जाता है।

इस बीच, विरासत के लिए, मैं ईसीएमएस्क्रिप्ट 5 में शामिल नई विधियों का उपयोग करना पसंद करता हूं जिसका अर्थ है ऑब्जेक्ट.क्रेट, ऑब्जेक्ट.डेफिनप्रॉपर्टीज आदि का उपयोग करना। वे आईई 9 में भी समर्थित हैं। इससे पहले मैंने कोस्टा द्वारा सुझाए गए 'लागू()' विधि का उपयोग किया था।

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