2012-10-20 20 views
9

Aşağıda gösterildiği gibi bir sınıf özelliğinde bir dizi işlevi barındırmak istiyorum.
Ne yazık ki, sınıfın ana kapsamına erişemeyecekler.Kahve sınıflarındakullanım kapsamı

Her iç içe geçmiş işlevi this referansına geçmeden çözebilir miyim?

class myClass 
    constructor: -> 
    @errors = [] 

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

Opsiyonel alternatif küresel this.errors özelliğine yazmaz: sonucu (

class myClass 

    constructor: -> 

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

Bu/@ yapıcıya bunları bağlamak için? – biziclop

+0

Yani yapıcı: -> @errors = [] @functions: doStuff -> ... '? – Industrial

+0

Belki de yağ oku kullanarak => http://coffeescript.org/#fat_arrow Ben bir coffeescript ustası değilim, üzgünüm :) – biziclop

cevap

3

JavaScript'inizde

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 

Ateş etmeyen alternatif yağ oku önerdi kullanarak , CoffeeScript de), yöntem, yöntemi içeren nesnenin this kullanın. Eğer sizin gibi örnek başa sürece

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

Bu genellikle, iyi çalışıyor:

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

JavaScript ile uğraşırken, ben fonksiyonlar için ad olan önleyeceğini - bu geçici çözümler ile bile, iyi oynamıyor . Örneğin, object.functions'da this nesnesine başvuruda bulunmayı deneyebilirsiniz, böylece object.functions'daki herhangi bir işlev buna erişebilir.

Bu, ilk çalışmaya, ancak obj2 gibi çalışmaz apply ya da üzerinde call, obj1.functions.alsoDoSomething.call(obj2) gibi özelliklerini kullanırken kafa karıştırıcı olabilir görünür
class MyClass 
    constructor: -> 
    @errors = [] 
    @functions.self = this 

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

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

hangi olamaz, doğru nesne (kullanıcı yerine obj2.functions yapmalıyım kafa karıştırıcı olmak).

Gerçek çözüm şu şekildedir: . JavaScript, bu gibi kötüye kullanım amaçlı değildir. Tüm nesne yöntemleri doğrudan nesne prototipinde olmalıdır. İçinde nesneniz varsa, bunun tüm yöntemleri nesnenizin yöntemleri değildir.

+0

Harika bir açıklama ve çözüm için teşekkür ederiz! – Industrial

2

GlitchMr yanıtının bir eki olarak, her bir denemenizin neden başarısız olduğunu açıklayacağım.

  1. functions nesne prototip üzerinde ilan edilir, böylece @errorsmyClass.errors için derlendi. Ancak, errors nesnesi bir örnek üye olarak değil, bir prototip üyesi olarak bildirilir.
  2. Bir nesne olması gerektiğinde, CoffeeScript'in işlev gösterimini kullanarak functions'u tanımlarsınız. Hata mesajı bir CoffeeScript derleyici hatasıdır; Bu sözdizimi hatası düzeltildikten sonra olması gerektiği gibi çalışır!
  3. Bu örnekte neden işe yaramadığını görüyorsunuz, bu yüzden size iki kez söylemeyeceğim!

Bu durum için fat arrow doğru kullanım örneği aşağıda verilmiştir.

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"] 

Umarız bu, hataların açığa çıkarılmasına ve CoffeeScript'in yağ okunun gücünün gösterilmesine yardımcı oldu!

+0

'=>' açıkladığınız için teşekkür ederiz – Industrial