2011-12-19 13 views
7

Ora sto facendo la transizione verso la scrittura di tutto il mio codice javascript usando Coffeescript, ma sono frustrato perché il più semplice degli esempi mi sta causando problemi. A partire da ora, ho fatto più di un'ora di ricerche senza essere in grado di trovare la risposta a questa ...Perché questa chiamata di funzione non funziona utilizzando 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> 

Come è chiaro dal codice di cui sopra, sto solo cercando di fare il chiama al servizio sayHi() dall'interno del gestore pronto di jQuery. Ma l'errore che sto ricevendo è la seguente:

TypeError Uncaught: undefined non è una funzione

per favore mi aiuti, secondo il compilatore e tutorial che ho letto questo lavoro 'dovrebbe' , Ma non so cosa sto facendo È terribilmente sbagliato per questo non eseguire :(

+0

L'ultima volta che ho controllato, i browser non hanno interpreti CoffeeScript ... o è che "il caffè-sript.js" copione tradurre il codice di CoffeeScript in JavaScript? –

+0

Hai provato a capovolgere le due affermazioni? Non ho mai lavorato con CoffeeScript ma suppongo che sia dovuto al fatto che chiami un metodo/funzione prima che sia stato definito (come in C) –

+0

@ Šime Vidas Ciò significa che ciò che sto facendo è sbagliato ....? – jlstr

risposta

11

text/coffeescript I tag hanno una differenza fondamentale rispetto ai tag text/javascript. Non si "eseguono" finché il documento non viene caricato. la libreria di script deve trovare tutti i tag di script del caffè e compilarli, e deve attendere fino al DOM r pronto per essere sicuro di trovarli tutti.

L'altra questione è che jQuery sparerà il callback pronto DOM immediatamente se l'evento già accaduto. E in questo caso lo ha.

Così, quando questo viene compilato a JS si ottiene questo:

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

Quindi, ciò che accade è:

  • dichiarare la variabile sayHi senza alcun valore, il che rende undefined.
  • Creare il callback pronto per DOM per jQuery che utilizza questa variabile.
  • jQuery esegue immediatamente la funzione di callback perché DOM ready è già successo.
  • La funzione di callback viene eseguita e tenta di eseguire sayHi() che non è ancora definito.
  • Dopo l'esecuzione della richiamata, sayHi viene quindi impostato sulla funzione che si desidera eseguire.

Ora, se questo è stato un normale tag JS, avrebbe potuto eseguire prima del documento caricato, e poi avrebbe funzionato bene perché da tempo la richiamata in realtà correva, poi sayHi sarebbe stato assegnato correttamente.

Per risolvere il problema è necessario assegnare la funzione PRIMA di eseguire il passaggio nella richiamata. Oppure puoi saltare interamente il $(->) dato che sai già DOM pronto a sparare. Ma in realtà, questo è uno dei motivi principali per cui non dovresti usare i tag coffeescript. Non è proprio come usare un tag JS. E uno dei tanti motivi per cui questo non è l'approccio raccomandato per l'uso di CoffeeScript su un sito web reale.

Quindi compilare lo script caffè prima il browser lo vede come uno sviluppatore responsabile :)

+0

Ma il browser esegue tutti gli elementi '

4

flip le dichiarazioni. Sembra che CoffeeScript abbia le stesse limitazioni del buon vecchio C in cui non è possibile effettuare una chiamata a una funzione/metodo finché non è stato definito nell'ordine del codice.

Quindi utilizzare

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

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

È possibile, sorta. Avrebbe funzionato, tranne che in questo caso il callback era in esecuzione immediatamente. Se funzionasse più tardi avrebbe funzionato bene. –

Problemi correlati