2014-04-06 6 views
6

के लिए जावास्क्रिप्ट कोड उत्पन्न करता है मेरे पास एक प्रश्न है कि टाइपस्क्रिप्ट सरल वर्ग विरासत के लिए जावास्क्रिप्ट कोड कैसे उत्पन्न करता है। नीचे कुछ जावास्क्रिप्ट कोड के बाद कुछ टाइपस्क्रिप्ट कोड है।टाइपस्क्रिप्ट सरल वर्ग विरासत

टाइपप्रति कोड:

class Animal { 
    constructor(public name: string) { } 
    move(meters: number) { 
     alert(this.name + " moved " + meters + "m."); 
    } 
} 

class Cat extends Animal { 
    constructor(name: string) { super(name); } 
    move() { 
     alert("run..."); 
     super.move(5); 
    } 
} 

जनरेट किया Javascript कोड:

var __extends = this.__extends || function (d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    __.prototype = b.prototype; 
    d.prototype = new __(); 
}; 
var Animal = (function() { 
    function Animal(name) { 
     this.name = name; 
    } 
    Animal.prototype.move = function (meters) { 
     alert(this.name + " moved " + meters + "m."); 
    }; 
    return Animal; 
})(); 

var Cat = (function (_super) { 
    __extends(Cat, _super); 
    function Cat(name) { 
     _super.call(this, name); 
    } 
    Cat.prototype.move = function() { 
     alert("run..."); 
     _super.prototype.move.call(this, 5); 
    }; 
    return Cat; 
})(Animal); 

आपको लगता है कि जावास्क्रिप्ट कोड उत्पन्न एक __extends(d, b) शामिल देखेंगे। यह फ़ंक्शन सभी बेस क्लास गुणों को व्युत्पन्न कक्षा में प्रतिलिपि बनाता है: d[p] = b[p];

मेरा प्रश्न यह है कि यह प्रतिलिपि क्यों आवश्यक है, बस Cat.prototype = _super; सेट करना ठीक था और जावास्क्रिप्ट प्रोटोटाइप आधारित विरासत के साथ इनलाइन था। आधार ctor गुणों को d[p] = b[p]; जैसे व्युत्पन्न सीटीआर की प्रतिलिपि बनाना स्मृति की बर्बादी लगता है।

+0

इस जावास्क्रिप्ट ** [प्रश्न] (http://stackoverflow.com/a/1535687/3487297) ** स्थिर गुणों के बारे में, जो @WiredPrairie की प्रतिक्रिया के साथ मिलकर है। – g4rce

उत्तर

4

प्रोटोटाइप पर स्थिर गुण/कार्य मौजूद नहीं हैं। prototype केवल तभी उपयोग किया जाता है जब new इंस्टेंस बनाया जाता है।

तो, पहला पाश बस स्थैतिक गुणों की प्रतिलिपि बनाता है (जिसमें फ़ंक्शन शामिल होंगे)। यह prototype पर कुछ भी कॉपी नहीं कर रहा है (for(var v in p) में prototype या प्रोटोटाइप पर घोषित गुण/फ़ंक्शन शामिल नहीं हैं)।

जावास्क्रिप्ट में prototype श्रृंखला को संरक्षित करने का सबसे अच्छा तरीका सुपर क्लास के उदाहरण के लिए उप-वर्ग के prototype को सेट करना है।

Cat.prototype = new Animal(); 

इस तरह, जब जावास्क्रिप्ट उससे मिलते-जुलते संपत्ति की तलाश में है, यह ठीक से वंशानुगत पदानुक्रम के माध्यम से प्रोटोटाइप श्रृंखला का पालन करेंगे: उपरोक्त मामले में, यह इस के बराबर होता है।

आप इसे सीधे सेट करते हैं:

Cat.prototype = Animal.prototype 

यही मतलब होगा के रूप में वे एक ही उदाहरण (जो आम तौर वांछनीय नहीं होगा) को इंगित होता है कि Catprototype के लिए किसी भी क्रम में परिवर्तन भी Animal पर असर पड़ेगा।

+0

अरे, लेकिन फ़ंक्शन __extends को पैराम के साथ बुलाया जा रहा है जो फ़ंक्शन ऑब्जेक्ट्स हैं: '__extends (बिल्ली, पशु)'।अगर वे 'बिल्ली = नई बिल्ली() थे; पशु = नया पशु(); __extends (बिल्ली, पशु) ', मैं समझता हूं कि आप क्या कह रहे हैं। हम 'animal.OwnProperty' ऑब्जेक्ट प्रॉपर्टी के बजाय 'Animal.OwnProperty' फ़ंक्शन प्रॉपर्टी की प्रतिलिपि क्यों बना रहे हैं? मैं जेएस के लिए नया हूं इसलिए शायद मुझे कुछ स्पष्ट याद आ रही है। – g4rce

+0

यह नहीं है कि विरासत कैसे करें या कैसे कोई व्यक्ति स्थिर गुणों के रूप में संदर्भित करेगा। वे फ़ंक्शंस हैं, जब 'new' के साथ बनाए जाते हैं, तो' इस 'सेट को नए इंस्टेंस के साथ फ़ंक्शन का एक उदाहरण बना देंगे। एक 'फ़ंक्शन' केवल एक ऑब्जेक्ट है, और 'new' के साथ उपयोग किए जाने पर तत्काल किया जा सकता है। यदि इसके बजाय एक नया उदाहरण पारित किया गया था, तो यह केवल एक ही उदाहरण का विस्तार करेगा, हर उदाहरण नहीं। – WiredPrairie

+0

यह उत्तर अभी तक एकमात्र सही है। –

0
d[p] = b[p];. 

ऐसा किया जाता है ताकि बी संपत्तियां डी के गुण हों।

मेरा प्रश्न यह है कि यह प्रतिलिपि क्यों आवश्यक है, बस Cat.prototype = _super सेट करना;

यह एक विवरण की तरह प्रतीत हो सकता है लेकिन प्रोटोटाइप पर "स्थैतिक" गुणों को सेट करने से अवांछनीय दुष्प्रभाव हो सकते हैं।

कल्पना करें कि आपके पास बी पर संपत्ति जैसी स्थिर है।

आप d.prototype.theStaticProperty पर कॉल किए बिना इस स्थिर संपत्ति तक पहुंचने के लिए चाहते हैं।

कैसे जावा या सी # works.if बी एक वर्ग एक सार्वजनिक स्थिर संपत्ति (या विधि) के रूप में है कि एक्स, तो डी कि बी फैली है यही कारण है कि यह भी एक सार्वजनिक स्थिर संपत्ति या विधि एक्स

+0

'd.prototype.theStaticProperty' 'new d()' कन्स्ट्रक्टर फ़ंक्शन का उपयोग करके बनाई गई सभी ऑब्जेक्ट्स के लिए स्वचालित रूप से सुलभ नहीं है। मुझे लगता है कि प्रोटोटाइप चेनिंग द्वारा पहले से ही संभाला जा चुका है, और यह है कि जेएस में विरासत कैसे काम करती है। व्युत्पन्न करने के लिए मूल गुणों की प्रतिलिपि बनाना सभी व्युत्पन्न वस्तुओं के बीच साझा करने के बजाय प्रत्येक मूल संपत्ति को ओवरराइड करना है। बीटीडब्ल्यू, क्या आप स्थैतिक गुणों के अवांछनीय साइड इफेक्ट्स पर विस्तार कर सकते हैं? – g4rce

+0

और यदि आप d.myStaticProp को कॉल करना चाहते हैं तो क्या होगा? बी के एक बच्चे वर्ग को दिया गया है जहां b.myStaticProp मौजूद है, अन्य वर्ग आधारित भाषाओं में? मैं यहां उदाहरणों के बारे में बात नहीं कर रहा हूं, लेकिन कक्षाओं के स्थिर गुण। आप इस तकनीक से सहमत नहीं हो सकते हैं लेकिन यह एक और बहस है, मैं आपको बता रहा हूं कि वे ऐसा क्यों करते हैं। यह सब कुछ है। – mpm

0

मुझे लगता है कि है प्रतिलिपि की आवश्यकता है क्योंकि हमें केवल उन्हीं तरीकों का उत्तराधिकारी होना चाहिए जो गुण नहीं हैं। पहली पंक्ति में हम वास्तव में वस्तु गुण बनाते हैं। प्रोटोटाइप केवल विधियों को रखता है। दूसरी पंक्ति इस तरह कोड से बदलाव आधार वर्ग प्रोटोटाइप को रोकने के लिए की जरूरत है:

Cat.prototype.catMethod = function() { /* ... */ } 

व्युत्पन्न वर्गों को अपने स्वयं के प्रोटोटाइप की आवश्यकता है। हम एक अनाम नाम समारोह को परिभाषित करते हैं। वास्तव में हमें केवल इसके प्रोटोटाइप की आवश्यकता है। this.constructor = d आवश्यक है यदि हम सही कन्स्ट्रक्टर संपत्ति के साथ व्युत्पन्न कक्षा के उदाहरण बनाना चाहते हैं। तीसरी पंक्ति में हमने अस्थायी फ़ंक्शन __ के लिए सही प्रोटोटाइप सेट किया है। यह वास्तव में बेस क्लास विधियों का विरासत है। आखिरी पंक्ति में हम व्युत्पन्न वर्ग का प्रोटोटाइप बनाते हैं।

+0

धन्यवाद, आपके बहुत सारे विश्लेषण समझ में आता है। एक प्रश्न जो मैं अभी भी समझना चाहता हूं वह यह है कि जब '__extends (बिल्ली, पशु) '(जहां' बिल्ली 'और' पशु 'दोनों कन्स्ट्रक्टर फ़ंक्शन ऑब्जेक्ट होते हैं), हम हर' Animal.property' को 'बिल्ली' में क्यों कॉपी करेंगे .property'। – g4rce

1

यह कक्षा पर स्थिर गुणों के बारे में है। कुछ कोड पर विचार करें:

class Mammal { 
    static descriptor = 'mammalian'; 

    constructor() {} 

    getLegs() { 
     return 4; // Good for most things 
    } 
} 

class OtherMammal extends Mammal { 
    // Default implementation is OK 
} 

class Human extends Mammal { 
    static descriptor = 'anthropic' 

    constructor() { 
     super(); 
    } 

    getLegs() { 
     return 2; // Being bipedal is great 
    } 
} 


function createMammal(classType: typeof Mammal) { 
    console.log('Creating a new ' + classType.descriptor + ' object'); 
    // ... 
} 

createMammal(Mammal); // "Creating a new mammalian object" 
createMammal(Human); // "Creating a new anthropic object" 
// Normal version of _extends 
createMammal(OtherMammal); // "Creating a new mammalian object" 
// If we had removed the line with d[p] = b[p]; 
createMammal(OtherMammal); // "Creating a new undefined object" 

नोट अंतिम पंक्ति - अगर हम व्युत्पन्न वर्ग निर्माता कार्य करने के लिए आधार वर्ग निर्माता समारोह से वस्तुओं की नकल नहीं करते, हम के स्थान पर व्युत्पन्न वर्ग निर्माता समारोह उपयोग नहीं कर सकते बेस क्लास कन्स्ट्रक्टर फ़ंक्शन। मैं इस कोड को एक टैब में चलाने और prototype और __proto__ प्रत्येक कक्षा के गुणों को बेहतर ढंग से समझने की सलाह दूंगा कि वास्तव में क्या हो रहा है।

टाइपस्क्रिप्ट में विचार यह है कि व्युत्पन्न वर्ग का कन्स्ट्रक्टर फ़ंक्शन अपने मूल वर्ग के कन्स्ट्रक्टर फ़ंक्शन का उप-प्रकार है। यह उपरोक्त की तरह कारखाने के पैटर्न के लिए अनुमति देता है।

यहां और प्रश्न के उत्तरों के आधार पर, ऐसा लगता है कि prototype और __proto__ के बीच कुछ भ्रम है। prototype बदलना new के माध्यम से बनाई गई वस्तुओं के __proto__ को बदलता है; यह संपत्ति लुकअप के परिणामों को प्रभावित नहीं करता है।

टाइपस्क्रिप्ट में स्थैतिक विरासत सी # में स्थिर विरासत से थोड़ा अलग है - पदानुक्रम में प्रत्येक वर्ग को स्थैतिक गुणों की अपनी प्रति प्राप्त होती है। यह हो सकता है कि आप क्या उम्मीद करते हैं या नहीं।

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