2012-06-18 6 views
7

मैं विरासत मैं हमेशा देखा है के लिए जावास्क्रिप्ट में इस व्यवहार को समझ में नहीं आता कि ऐसा तरह परिभाषित:मैं Child.prototype = parent.Prototype का उपयोग क्यों नहीं करूं बल्कि Child.prototype = new parent(); जावास्क्रिप्ट विरासत के लिए?

function GameObject(oImg, x, y) { 

    this.x = x; 
    this.y = y; 
    this.img = oImg; 

    this.hit = new Object(); 
    this.hitBox.x = x; 
    this.hitBox.y = y; 
    this.hitBox.width = oImg.width; 
    this.hitBox.height = oImg.height; 

} 

Spaceship.prototype = new GameObject(); 
Spaceship.prototype.constructor = Spaceship; 

function Spaceship(){ 
    console.log("instantiate ship"); 
    GameObject.apply(this, arguments); 
    this.vx = 0; 
    this.vy = 0; 
    this.speed = 3; 
    this.friction = 0.94; 
} 

लेकिन मेरे मामले में, इन पंक्तियों:

this.hitBox.width = oImg.width; 
    this.hitBox.height = oImg.height; 

जब मैं एक सांत्वना करना .log (यह) मेरे स्पेसशिप कन्स्ट्रक्टर में, मैं देख सकता हूं कि प्रोटो संपत्ति GameObject के बजाय स्पेसशिप पर सेट है, अगर मैं उन्हें हटा देता हूं, तो यह GameObject पर सेट है।

और अगर मैं का उपयोग करें:

Spaceship.prototype = GameObject.prototype; 

मैं उसके साथ कोई और अधिक समस्याएं हैं। कारण मुझे मैं एक ऐड() विधि के साथ एक और वस्तु है और यह जाँच करता है कि इस कोड के साथ GameObject की वस्तु inerhits कि है कि इस ब्लॉक:

if(object instanceof GameObject) 

मुझे समझ नहीं आता क्या उन दो पंक्तियों शायद परिवर्तन कर सकते हैं ताकि जब वे मौजूद हों तो विरासत टूट जाती है और मुझे यकीन नहीं है कि विरासत करना दूसरा तरीका अच्छा है। क्या कोई मुझे इसके बारे में बता सकता है? :)

+0

ध्यान दें कि 'exampleof' खराब अभ्यास है, यदि आप इसका उपयोग करने से बच सकते हैं, तो आपको शायद चाहिए। – Jasper

+1

@ जैस्पर: क्यों? – Bergi

+0

@ बर्गि यह बहुरूपता का उचित उपयोग नहीं है और आपके विरासत के पेड़ में अधिक कक्षाएं जोड़े जाने पर समस्याएं हो सकती हैं। दूसरे शब्दों में, 'exampleof' आमतौर पर ओपन/क्लोज़ेड सिद्धांत के साथ बहुत अच्छी तरह से मिश्रण नहीं करता है। – Jasper

उत्तर

13

आप

Spaceship.prototype = GameObject.prototype;

तब वे दोनों, एक ही वस्तु को देखें तो आप के रूप में अच्छी GameObject में सब कुछ हो सकता है, आप Spaceship.prototype के लिए कुछ जोड़ते हैं, तो यह GameObject.prototype में जोड़ दिया जाएगा करते हैं भी। असाइनमेंट के बाद आप Spaceship.prototype पर कुछ जोड़कर आसानी से इसका परीक्षण कर सकते हैं। For example, in your case you can see that GameObject.prototype.constructor is actually Spaceship

के लिए

Spaceship.prototype = new GameObject(); 

यह निर्माता अवांछित दुष्प्रभाव हो हो सकता है का आह्वान किया है, आप के बजाय का उपयोग करना चाहते:

:

Spaceship.prototype = Object.create(GameObject.prototype); 

कहाँ इस्तेमाल किया Object.create कार्यक्षमता यहाँ करने के लिए नीचे आता है

Object.create = function(proto) { 
    function f(){} 
    f.prototype = proto; 
    return new f; 
}; 

आधुनिक ब्राउज़र में पहले से ही कार्य है।

+0

आपकी समस्या का समाधान करने के लिए बहुत बहुत धन्यवाद और मैं अब विरासत को बेहतर समझता हूं! :) –

+0

@GeoffreyHug क्या आपने देखा कि आप कहीं भी '.hitbox' को परिभाषित नहीं करते हैं? 'this.hit = नया ऑब्जेक्ट(); this.hitBox.x = x; 'शायद यह होना चाहिए 'hitBox = new object();' – Esailija

+0

हां, मैंने टिप्पणी पोस्ट करने के बाद इसे देखा, मैंने बहुत सारे बदलाव किए हैं ^^ –

2

यह कभी भी सही ढंग से समझाया नहीं गया था कि आप this.hitBox के साथ अजीब व्यवहार क्यों कर रहे थे (मुझे लगता है कि आप यही कहने की कोशिश कर रहे थे)।

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

इस के साथ समस्या यह है कि अगर है कि निर्माता किसी भी लाइनों कि this को परिवर्तनशील वस्तुओं आवंटित है, तो उन वस्तुओं और उन वस्तुओं है कि प्रोटोटाइप पर गुण किसी भी संशोधन में दिखाई देंगे बच्चे प्रकार के सभी उदाहरणों हो जाएगा :

Spaceship.prototype = new GameObject(); 
Spaceship.prototype.constructor = Spaceship; 

var sps1 = new Spaceship(); 
var sps2 = new Spaceship(); 

sps1.hitBox.x = 9; 
sps2.hitBox.x = 12; 
console.log(sps1.hitBox.x); // 12 (oh noes! what happened) 
console.log(sps2.hitBox.x); // 12 

(वहाँ अन्य, के साथ दृष्टिकोण "एक प्रोटोटाइप बनाने के लिए एक निर्माता कहते हैं" इसी तरह की समस्याओं कर रहे हैं, लेकिन मैं सिर्फ इसे यहाँ उस बिंदु पर छोड़ देंगे)

@ Esailija के सुझाव Object.create(baseObject) उपयोग करने के लिए टी है वह इस समस्या को हल करने के लिए पहला कदम है। यह एक नई वस्तु बनाता है जिसका प्रोटोटाइप baseObject है, लेकिन कन्स्ट्रक्टर में स्थापित सामान के बिना (यह एक अच्छी बात है, लेकिन इसके लिए जिम्मेदार होना आवश्यक है ...)।

जैसा कि मैंने अभी कहा है, यह एक ऑब्जेक्ट बनाएगा जहां माता-पिता के कन्स्ट्रक्टर में प्रारंभिक तर्क कभी नहीं चला है, लेकिन ज्यादातर मामलों में तर्क वस्तु की कार्यक्षमता के लिए प्रासंगिक है। तो एक और बात आपको बस इतना करना, बच्चे निर्माता माता पिता निर्माता फोन है जो वहाँ है:

function Spaceship(oImg, x, y) { 
    // call parent constructor on this object and pass in arguments. 
    // you could also use default values for the arguments when applicable 
    GameObject.call(this, oImg, x, y); 

    // remainder of Spaceship constructor... 
} 

यह सुनिश्चित होगा कि माता-पिता निर्माता तर्क अलग से हर नए Spaceship के लिए चलाता है, और किया जाता है आवश्यक प्रारंभिक कार्य।

0
function GameObject(oImg, x, y) { 

    this.x = x; 
    this.y = y; 
    this.img = oImg || {width:null, height: null}; 

    this.hitBox = new Object(); 
    this.hitBox.x = x; 
    this.hitBox.y = y; 
    this.hitBox.width = this.img.width; 
    this.hitBox.height = this.img.height; 

} 


function Spaceship(){ 
    GameObject.apply(this, arguments); 
    this.vx = 0; 
    this.vy = 0; 
    this.speed = 3; 
    this.friction = 0.94; 
} 
Spaceship.prototype = new GameObject(); 

var sps1 = new Spaceship(); 
var sps2 = new Spaceship(); 

sps1.hitBox.x = 9; 
sps2.hitBox.x = 12; 
console.log(sps1.hitBox.x); // 9 
console.log(sps2.hitBox.x); // 12 
संबंधित मुद्दे