2012-04-12 59 views
10

我学习的CoffeeScript,和我有一个轻微的头痛我还不太能弄清楚。如果我创建一个对象来做某些事情,我偶尔需要一个实例变量来为该对象在方法之间共享。举例来说,我想这样做:CoffeeScript的实例变量

testObject = 

    var message # <- Doesn't work in CoffeeScript. 

    methodOne: -> 
    message = "Foo!" 

    methodTwo: -> 
    alert message 

但是,你不能在CoffeeScript中使用var,并且没有声明message只是内部methodOne可见。那么,如何在CoffeeScript中的对象中创建实例变量?


更新:在我的例子固定错字所以这些方法实际上是方法:)

+0

顺便说一句,我知道我能做到'的消息=“ “',但我真的只是希望变量为空,所以我可以根据存在设置行为,而不是更复杂的检查,看看它是不是”空白“等。 – Andrew 2012-04-12 21:25:53

+0

你也可以设置'message = null'这是什么你不想要? – Sandro 2012-04-12 21:34:40

+0

当我尝试'message = null'时,我得到'ParseError Unexpected'TERMINATOR'' – Andrew 2012-04-12 21:41:31

回答

12

你不能那样。引述language reference

因为你不必var关键字直接访问,这是不可能的目的阴影外的变量,你可能只提到它。所以要小心,如果您正在编写深度嵌套函数,您不会意外地重用外部变量的名称。

你正在试图做的JS是不可能的。然而无论怎样,这将相当于

testObject = { 
    var message; 
    methodOne: message = "Foo!", 
    methodTwo: alert(message) 
} 

这是无效的JS,因为你不能声明一个变量在这样的对象中;你需要使用函数来定义方法。例如,在CoffeeScript中:

testObject = 
    message: '' 
    methodOne: -> 
     this.message = "Foo!" 
    methodTwo: -> 
     alert message 

您还可以使用@作为快捷方式的this.message“这个”,即@message代替。

或者考虑使用CoffeeScript中的class syntax

class testObject 
    constructor: -> 
     @message = '' 

    methodOne: -> 
     @message = "Foo!" 

    methodTwo: -> 
     alert @message 
+0

很好的例子,谢谢! – Andrew 2012-04-12 21:44:02

1

您可以定义属性:

message: null 

但是,你是不是现在定义方法 - 您需要->

然后,参考实例属性的方法中,用@前缀属性名。

testObject = 

    message: null 

    methodOne: -> 
    @message = "Foo!" 

    methodTwo: -> 
    alert @message 
+0

' - >'不是必需的:参见[my fixed version](http://coffeescript.org/#try:testObject%20%3D%20%0A%0A%20%20methodOne%3A%0A%20% 20%20%20%40%消息%20%3D%20%22Foo!%22%0A%0A%20%20methodTwo%3A%0A%20%20%20%20%20%40message) – 2012-04-12 21:31:55

+0

@KristofferSHansen your version isn' t固定;正如你可以通过在该页面上按'运行'所看到的那样,它会立即显示一个警告对话框,这可能不是安德鲁之后的事情,更可能是他希望推迟执行直到该方法被调用。 – Lauren 2012-04-12 21:34:48

+0

@KristofferSHansen它用于功能/方法。没有它,'methodTwo'被设置为调用'alert'的结果,而不是调用'alert'的函数。 – 2012-04-12 21:35:08

5

只需添加到@劳伦的答案,你想基本上是module pattern

testObject = do -> 

    message = null 

    methodOne = -> 
    message = "Foo!" 

    methodTwo = -> 
    alert message 

    return { 
    methodOne 
    methodTwo 
    } 

其中message是仅适用于这些方法的“专用”变量。

根据上下文,你也可以在对象之前宣布的消息,使得它适用于这两种方法(如果在这种情况下执行):

message = null 

testObject = 
    methodOne: -> message = "Foo!" 
    methodTwo: -> alert message 
+0

感谢您的额外信息,这是有帮助的! – Andrew 2012-04-13 02:20:52

+0

正确,但是你的代码有点bug:'do'只会创建一个闭包,所以你不能定义属性,而应该使用变量('methodOne = - > ...'等)。另外,return语句应该可能是'{methodOne:methodOne,methodTwo:methodTwo}'。当然你可以把你的方法定义放入return语句中去。 – 2012-04-16 22:28:20

+1

@JulianD。 * copy&pasta * :) return语句使用[解构赋值](http://coffeescript.org/#destructuring)。 – 2012-06-21 07:39:17