2011-12-19 24 views
7

Ahora estoy haciendo la transición hacia la escritura de todos mis códigos javascript usando Coffeescript, pero estoy frustrado porque el ejemplo más simple me está causando problemas. A partir de ahora, he hecho más de una hora de la investigación, sin ser capaz de encontrar la respuesta a esta ...¿Por qué esta función no funciona usando Coffeescript?

<!DOCTYPE html> 
<html> 
<head> 
    <script src="http://code.jquery.com/jquery-latest.js"></script> 
    <script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js" type="text/javascript" charset="utf-8"></script> 
    <link href="sheet.css" rel="stylesheet" type="text/css" media="screen" /> 
    <script type="text/coffeescript"> 
    $ -> 
     sayHi() 

    sayHi = -> 
     alert 'Hi there!' 
    </script> 
</head>  
<body> 
    <div id="all"> 
    </div> 
</body> 
</html> 

Como es evidente en el código anterior, sólo estoy tratando de hacer el llamar a la función sayHi() desde el manejador listo de jQuery. Pero el error que estoy recibiendo es la siguiente:

TypeError no detectada: indefinido no es una función

Por favor, ayúdame, según el compilador y tutoriales que he leído este 'debe ' trabajo , Pero no sé lo que estoy haciendo muy mal para que esto no funcionar :(

+0

Que yo sepa, los navegadores no tienen intérpretes CoffeeScript ... o es que el "café-sript.js" script de traducción del código JavaScript en CoffeeScript? –

+0

¿Has probado voltear las dos declaraciones? Nunca he trabajado con CoffeeScript pero supongo que se debe al hecho de que está llamando a un método/función antes de que se haya definido (como en C) –

+0

@ Šime Vidas Lo que significa que lo que estoy haciendo mal es ....? – jlstr

Respuesta

11

text/coffeescript etiquetas tienen una diferencia clave entre text/javascript etiquetas. Ellos no "correr" hasta que se carga el documento. esto se debe a que el café la biblioteca de scripts tiene que encontrar todas las etiquetas de script de café y compilarlas, y debe esperar hasta que el DOM r listo para que pueda estar seguro de encontrarlos a todos.

El otro problema es que jQuery disparará la devolución de llamada lista para DOM inmediatamente si el evento ya ocurrió. Y en este caso tiene.

Y cuando esto se compila a JS se obtiene lo siguiente:

var sayHi; 
$(function() { 
    return sayHi(); 
}); 
sayHi = function() { 
    return alert('Hi there!'); 
}; 

Así que lo que sucede es:

  • declarar la variable sayHi sin valor, por lo que es undefined.
  • Crea la devolución de llamada lista para DOM para jQuery que usa esta variable.
  • jQuery ejecuta la función de devolución de llamada inmediatamente porque DOM listo ya ha sucedido.
  • La función de devolución de llamada se ejecuta e intenta ejecutar sayHi() que aún no está definido.
  • Después de que se ejecuta la devolución de llamada, sayHi se establece en la función que desea ejecutar.

Ahora bien, si esto era una etiqueta normal de JS, que podría haber corrido antes de que el documento cargado, y luego se hubiera funcionado bien porque por el tiempo de la devolución de llamada en realidad se acabó, entonces sayHi habría sido asignado correctamente.

Para solucionarlo debe asignar la función ANTES de ejecutar pasar en la devolución de llamada. O puede omitir el $(->) en su totalidad, ya que sabe que DOM ya está listo. Pero en realidad, esta es una de las principales razones por las que realmente no deberías usar etiquetas coffeescript. Realmente no es lo mismo que usar una etiqueta JS. Y una de las muchas razones por las que este no es el enfoque recomendado para usar CoffeeScript en un sitio web real.

Así compilar el script de café antes de su navegador lo ve como un promotor responsable :)

+0

Pero el navegador ejecuta todos los elementos '

4

tirón de las declaraciones. Parece que CoffeeScript tiene las mismas limitaciones que la antigua C, donde no puedes hacer una llamada a una función/método hasta que se haya definido en el orden de tu código.

Así utilizar

<script type="text/coffeescript"> 
    sayHi = -> 
    alert 'Hi there!' 

    $ -> 
    sayHi() 
</script> 
+0

Puedes, sorta. Hubiera funcionado, excepto en este caso, la devolución de llamada se estaba ejecutando inmediatamente. Si se ejecutó más tarde habría funcionado bien. –

Cuestiones relacionadas