2012-10-20 38 views
9

我想在類屬性中嵌套一些函數,如下所示。
不幸的是,他們無法訪問課程的主要範圍。coffeescript類中的範圍

我可以解決這個問題,而不通過每個嵌套函數參考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

你的意思是'構造函數: - > @errors = [] @functions:doStuff - > ...''? – Industrial

+0

也許使用胖箭頭=> http://coffeescript.org/#fat_arrow我不是一個咖啡的主人,對不起:) – biziclop

回答

3

在JavaScript中(作爲結果,CoffeeScript),方法使用包含方法的對象的this

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

這通常效果很好,除非你處理例如像您一樣的:

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

當用JavaScript處理,我會避免對功能的命名空間 - 它不會與解決方法發揮出色,甚至。例如,您可以嘗試在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!" 

這出現在第一個工作,但是當你使用的是像applycall就可以了,obj1.functions.alsoDoSomething.call(obj2)屬性將不會爲obj2工作可能會產生混淆是不正確的對象(用戶應該做的,而不是obj2.functions其能混亂)。

真正的解決辦法是:不要。 JavaScript不打算像這樣濫用。所有的對象方法應該直接在對象原型中。如果你有對象,它的所有方法都不是你的對象的方法。

+0

謝謝你提供了一個很好的解釋和解決方法! – Industrial

2

作爲GlitchMr的答案的附錄,我將解釋爲什麼你的每一次嘗試失敗。

  1. functions對象被宣佈原型,所以@errors被編譯成myClass.errors。但是,errors對象被聲明爲實例成員,而不是原型成員。
  2. 使用CoffeeScript的函數表示法定義functions時,它應該是一個對象。錯誤消息是一個CoffeeScript編譯器錯誤;修復此語法錯誤後,它的工作原理應該如此!
  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"] 

希望這有助於澄清其錯誤,並顯示CoffeeScript中的脂肪箭頭的力量!

+0

謝謝你解釋'=>' – Industrial