2012-04-12 24 views
10

Estoy aprendiendo CoffeeScript, y tengo un pequeño dolor de cabeza que no he podido descifrar. Si creo un objeto para hacer ciertas cosas, de vez en cuando necesito que una variable de instancia para ese objeto se comparta entre métodos. Por ejemplo, me gustaría hacer esto:Variable de instancia de CoffeeScript

testObject = 

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

    methodOne: -> 
    message = "Foo!" 

    methodTwo: -> 
    alert message 

Sin embargo, no se puede utilizar en var CoffeeScript, y sin que la declaración message sólo es visible en el interior methodOne. Entonces, ¿cómo se crea una variable de instancia en un objeto en CoffeeScript?


Actualización: error tipográfico fijo en mi ejemplo por lo que los métodos son en realidad métodos :)

+0

Por cierto soy consciente de que podía hacer 'message =" "', pero realmente sólo quiero la variable a tener un valor nulo para poder establecer el comportamiento basado en la existencia en lugar de un cheque más complejo para ver si no es 'en blanco', etc. – Andrew

+0

también puede configurar 'message = null' que es lo quieres no? – Sandro

+0

Cuando intento 'message = null' obtengo' ParseError inesperado 'TERMINATOR'' – Andrew

Respuesta

12

No le puede gustar eso. Para citar el language reference:

Debido a que usted no tiene acceso directo a la palabra clave var, es imposible a la sombra de una variable externa a propósito, es posible que sólo se refieren a ella. Así que tenga cuidado de no reutilizar accidentalmente el nombre de una variable externa, si está escribiendo una función profundamente anidada.

Sin embargo lo que estamos tratando de hacer no sería posible en JS bien, sería equivalente a

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

que no es JS válidos, ya que no se puede declarar una variable en un objeto como ese; necesita usar funciones para definir métodos. Por ejemplo, en CoffeeScript:

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

También puede utilizar @ como un atajo para 'esto'., Es decir, en lugar de @messagethis.message.

Alternativamente considerar el uso de CoffeeScript class syntax:

class testObject 
    constructor: -> 
     @message = '' 

    methodOne: -> 
     @message = "Foo!" 

    methodTwo: -> 
     alert @message 
+0

¡Gran ejemplo, gracias! – Andrew

1

se puede definir la propiedad con:

message: null 

embargo, no está actualmente definición de métodos: necesita -> para eso.

Luego, para hacer referencia a las propiedades de instancia dentro de los métodos, escriba los nombres de las propiedades con @.

testObject = 

    message: null 

    methodOne: -> 
    @message = "Foo!" 

    methodTwo: -> 
    alert @message 
+0

-> 'no se requiere: véase [mi versión fija] (http://coffeescript.org/#try:testObject%20%3D%20%0A%0A%20%20methodOne%3A%0A%20% 20% 20% 20% 20% 40message% 3D% 20% 22Foo!% 22% 0A% 0A% 20% 20methodTwo% 3A%% 20% 20% 20% 20% 20alert% 40message 0A) –

+0

@KristofferSHansen su versión ISN' t fijo; como puede ver presionando 'Ejecutar' en esa página, mostraría un cuadro de diálogo de alerta inmediatamente, y probablemente eso no sea lo que persiga Andrew, más probablemente quiera diferir su ejecución hasta que se llame a ese método. – Lauren

+0

@KristofferSHansen Es para funciones/métodos. Sin él, 'methodTwo' está configurado para el resultado de llamar' alert', no una función que a su vez llama 'alert'. –

5

sólo para añadir a @ respuesta de Lauren, lo que quería es básicamente el module pattern :

testObject = do -> 

    message = null 

    methodOne = -> 
    message = "Foo!" 

    methodTwo = -> 
    alert message 

    return { 
    methodOne 
    methodTwo 
    } 

Donde message es una variable "privada" solo disponible para esos métodos.

Dependiendo del contexto también se puede declarar el mensaje antes de que el objeto de modo que esté disponible para ambos métodos (si se ejecuta en este contexto):

message = null 

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

Gracias por la información adicional, ¡esto es útil! – Andrew

+0

correcta, pero su código es un poco con errores: 'do' simplemente crear un cierre, que por lo tanto no se puede definir propiedades, pero debe utilizar en lugar vars (' metadona = -> ... 'etc.) Además, la instrucción de retorno debe, probablemente, be '{methodOne: methodOne, methodTwo: methodTwo}'. Por supuesto, podría poner las definiciones de sus métodos en la declaración de devolución en su lugar ... –

+1

@JulianD. * copy & pasta * :) La declaración de devolución usa [asignación desestructurada] (http://coffeescript.org/#destructuring). –

Cuestiones relacionadas