2012-10-20 16 views
9

मैं नीचे दिखाए गए वर्ग संपत्ति के अंदर कई कार्यों को घोंसला करना चाहता हूं।
दुर्भाग्यवश, उन्हें कक्षा के मुख्य दायरे तक पहुंच नहीं मिलेगी।कॉफ़ीस्क्रिप्ट कक्षाओं में स्कोप

क्या मैं प्रत्येक नेस्टेड फ़ंक्शन को this पर संदर्भित किए बिना इसे हल कर सकता हूं?

class myClass 

    constructor: -> @errors = [] 

    doSomething: -> @errors.push "I work as expected" 

    functions: 
    doStuff: -> 
     @errors.push "I cant access @errors" # => TypeError: Cannot call method 'push' of undefined 

    ugly: (context) -> 
     context.errors.push "It works, but I am ugly" # Works fine but requires scope injection 

गैर काम वैकल्पिक सुझाव वसा तीर का उपयोग:

class myClass 
    constructor: -> 
    @errors = [] 

    @functions: 
     doStuff: => 
     @errors.push "I wont work either" # TypeError: Cannot call method 'toString' of undefined 

वैकल्पिक विकल्प है, जो वैश्विक this.errors संपत्ति के बारे में नहीं है: (परिणाम के रूप में

class myClass 

    constructor: -> 

    @functions = 
     errors: [] 
     doStuff: -> 
     @errors.push "I will write to functions.errors only" 
+0

उन्हें कन्स्ट्रक्टर में/@ को बाध्य करना? – biziclop

+0

आपका मतलब है 'कन्स्ट्रक्टर: -> @ लेर्स = [] @ फ़ंक्शन: डूस्टफ -> ...'? – Industrial

+0

शायद वसा तीर => http://coffeescript.org/#fat_arrow का उपयोग कर मैं एक कॉफ़ीस्क्रिप्ट मास्टर नहीं हूं, क्षमा करें :) – biziclop

उत्तर

3

जावास्क्रिप्ट में , कॉफीस्क्रिप्ट भी), विधियों में विधि के this का उपयोग करें।

method()     // this == globalObject 
object.method()   // this == object 
Math.random()    // this == Math 

यह आमतौर पर अच्छी तरह से काम करता है जब तक कि आप उस तरह के उदाहरण के साथ सौदा:

object.functions.method() // this == object.functions 

जब जावास्क्रिप्ट के साथ काम कर, मैं कार्यों के लिए नाम स्थान होने से बचने होगा - यह अच्छी तरह से, यहां तक ​​कि समाधान के साथ खेलने नहीं करता है । उदाहरण के लिए, आप object.functions में this ऑब्जेक्ट को संदर्भ डालने का प्रयास कर सकते हैं, इसलिए object.functions में कोई भी कार्य उस तक पहुंच पाएगा।

class MyClass 
    constructor: -> 
    @errors = [] 
    @functions.self = this 

    doSomething: -> 
    @errors.push "I work as expected" 

    functions: 
    alsoDoSomething: -> 
     @self.errors.push "Also works!" 

यह पहली बार में काम करने के लिए, लेकिन जब आप apply या call उस पर, obj1.functions.alsoDoSomething.call(obj2) की तरह गुण का उपयोग कर रहे obj2 के रूप में काम नहीं करेगा आप भ्रमित हो सकते प्रकट होता है न सही वस्तु (उपयोगकर्ता बजाय obj2.functions करना चाहिए है जो कर सकते हैं भ्रमित हो)।

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

+0

एक महान स्पष्टीकरण और कामकाज के लिए धन्यवाद! – Industrial

2

GlitchMr के उत्तर में एक परिशिष्ट के रूप में, मैं समझाउंगा कि आपके प्रत्येक प्रयास विफल क्यों हुआ।

  1. functions वस्तु प्रोटोटाइप पर घोषित किया जाता है, तो @errorsmyClass.errors को संकलित किया गया है। हालांकि, errors ऑब्जेक्ट को एक इंस्टेंस सदस्य के रूप में घोषित किया गया है, प्रोटोटाइप सदस्य नहीं।
  2. आप कॉफीस्क्रिप्ट के फ़ंक्शन नोटेशन का उपयोग करते हुए functions को परिभाषित करते हैं, जब यह ऑब्जेक्ट होना चाहिए। त्रुटि संदेश एक कॉफीस्क्रिप्ट संकलक त्रुटि है; इस वाक्यविन्यास त्रुटि को ठीक करने के बाद, यह काम करता है जैसे यह चाहिए!
  3. आप इस उदाहरण का प्रस्ताव देते हैं कि यह क्यों काम नहीं करता है, इसलिए मैं आपको दो बार नहीं बताऊंगा!

इस परिस्थिति के लिए fat arrow के सही उपयोग का एक उदाहरण यहां दिया गया है।

class MyClass 

    constructor: -> 
    @errors = [] 
    @functions = 
     doStuff: => 
     @errors.push "I can and do access @errors" 

c = new MyClass 
c.functions.doStuff() 
console.log c.errors # ["I can and do access @errors"] 

उम्मीद है कि इससे त्रुटियों को नष्ट करने और कॉफीस्क्रिप्ट के वसा तीर की शक्ति दिखाने में मदद मिलेगी!

+0

'=>' समझाए जाने के लिए धन्यवाद – Industrial