2012-01-30 15 views
16

The documentation में कई वर्गों का विस्तार वर्णन करती हैं कि एक वर्गकॉफी स्क्रिप्ट

class Zebra extends Animal 
    ... 

विस्तार करने के लिए लेकिन मैं कई वर्गों कैसे विस्तार करते हैं? निम्नलिखित नहीं करता है काम

class Sidebar extends Controller, EventEmitter 
    ... 

लेकिन मैंने किया चाहते हैं। इसके पीछे जावास्क्रिप्ट __extend फ़ंक्शन का उपयोग करके कक्षाओं की किसी भी संख्या को बढ़ाने में सक्षम है, लेकिन क्या कॉफी-स्क्रिप्ट में ऐसा करने का कोई तरीका है?

+0

आप इस चर्चा पर एक नजर है कर सकते हैं: https://github.com/ jashkenas/कॉफी-स्क्रिप्ट/मुद्दों/452 – qiao

+0

सूड ... यह मेरे लिए अच्छा नहीं है – Hubro

+0

जावास्क्रिप्ट प्रोटोटाइप विरासत का उपयोग करता है ... दृश्य के पीछे, एक श्रृंखला बनाने के लिए एकल संपत्ति 'प्रोटोटाइप' का उपयोग करता है ... आप "विरासत" हो सकता है एफ रोम एकाधिक ऑब्जेक्ट्स केवल तभी वस्तुएं प्रोटोटाइप श्रृंखला होती हैं ... उदा। ज़ेबरा शाकाहारी एनामल और शाकाहारी विस्तार कर सकता है एनिमल पशु को बढ़ाता है। – Jaider

उत्तर

37

मान लीजिए कि मैं सिर्फ अपने प्रश्न का उत्तर दूंगा। जिस तरह से मैंने इसे संभाला, जिस तरह से मैं कक्षाओं से अपने सभी वर्गों को विस्तारित करता हूं, "सुपर क्लास" (नाम कोई फर्क नहीं पड़ता)। उस वर्ग से मैं कक्षाओं की किसी भी संख्या का विस्तार कर सकता हूं। वैसे भी वर्ग लगता है कि यह

moduleKeywords = ['included', 'extended'] 

class SuperClass 
    @include: (obj) -> 
     throw('include(obj) requires obj') unless obj 
     for key, value of obj.prototype when key not in moduleKeywords 
      @::[key] = value 

     included = obj.included 
     included.apply(this) if included 
     @ 

सुंदर ज्यादा सिर्फ Spine से चुरा लिया। एक वर्ग के सुपर क्लास से बढ़ाया का एक उदाहरण:

class Sidebar extends SuperClass 

    # Include some other classes 
    @include Controller 
    @include EventEmitter 

    ### 
    Constructor function 
    ### 
    constructor: -> 
     # Call extended constructors 
     Controller.call @ 
     EventEmitter.call @ 

     console.log 'Sidebar instantiated' 

सूचना है कि विरासत में मिला वर्ग 'निर्माता वर्ग समारोह @/this संदर्भ के रूप में के साथ कहा जाता है कॉल करने के लिए। मैं अभी तक वर्ग कार्यों का विस्तार करने की जरूरत नहीं है, लेकिन मुझे लगता है यह बहुत माता पिता निर्माता बुला के समान है:

someFunction: -> 
    ExtendedClass::someFunction.call @ 

इस पोस्ट को संपादित करें यदि मैं गलत हूँ। इसके अलावा वर्ग विरासत शब्दावली की मेरी कमी के लिए क्षमा करें - मैं कोई विशेषज्ञ हूँ


अद्यतन: एक भी कि स्वचालित रूप से इन्स्टेन्शियशन पर सभी शामिल कक्षाओं के लिए निर्माता कहा जाता है सुपर क्लास के लिए एक निर्माता निर्धारित कर सकते हैं। इस तरह आपको उप-वर्ग से super() पर कॉल करने की आवश्यकता होगी। मुझे इसके साथ परेशान नहीं है हालांकि

+0

मुझे लगता है कि सुपर कॉलिंग() काम नहीं करेगा।आपको '@ include'd ऑब्जेक्ट की श्रेणी को संग्रहीत करने के लिए किसी प्रकार की सरणी की आवश्यकता होगी। जो काम नहीं करेगा क्योंकि आपको इस वैरिएबल को '[] 'में रीसेट करने की आवश्यकता है। – Atmocreations

6

इसे mixin के रूप में जाना जाता है। कॉफीस्क्रिप्ट उन्हें कभी भी मूल रूप से शामिल नहीं करेगा क्योंकि आप कक्षा अनुभाग में the CoffeeScript FAQ पर पढ़ सकते हैं। लेकिन वहां in this Gist, Little Book में, और this one में जेएस के लिए कॉफीस्क्रिप्ट क्लासेस के साथ काम करने लगता है, वहां कई कार्यान्वयन हैं।

2

आप छोटे सहायक का उपयोग कर सकते हैं, जो सही कॉल super के साथ उचित प्रोटोटाइप श्रृंखला बनाते हैं। श्रृंखला में मौजूदा वर्गों का उल्लंघन नहीं, उनकी "अनुमानों" का उपयोग करता

https://gist.github.com/darrrk/75d6a6a4d431e7182888

virtual_class = (classes...)-> 
    classes.reduceRight (Parent, Child)-> 
    class Child_Projection extends Parent 
     constructor: -> 
     # Temporary replace Child.__super__ and call original `constructor` 
     child_super = Child.__super__ 
     Child.__super__ = Child_Projection.__super__ 
     Child.apply @, arguments 
     Child.__super__ = child_super 

     # If Child.__super__ not exists, manually call parent `constructor` 
     unless child_super? 
      super 

    # Mixin prototype properties, except `constructor` 
    for own key of Child:: 
     if Child::[key] isnt Child 
     Child_Projection::[key] = Child::[key] 

    # Mixin static properties, except `__super__` 
    for own key of Child 
     if Child[key] isnt Object.getPrototypeOf(Child::) 
     Child_Projection[key] = Child[key] 

    Child_Projection 

उदाहरण:

class My extends virtual_class A, B, C 
संबंधित मुद्दे