2010-09-26 12 views
8

So che esistono diversi modi per definire una funzione in JavaScript. Due dei più comuni sono:Cosa succede in JavaScript quando uso la dichiarazione di funzione "tradizionale" in stile C?

(1) function add (a, b) { 
     return a + b; 
    } 

(2) var add = function (a, b) { 
     return a + b; 
    } 

Sto bene con l'idea di una funzione come un oggetto che può essere passato in giro, proprio come qualsiasi altra variabile. Quindi capisco perfettamente cosa stia facendo (2). Sta creando una funzione e assegnando a add (diciamo che questo è nell'ambito globale, quindi add è una variabile globale) detta funzione. Ma cosa succede se uso invece lo (1)? So già che fa la differenza nell'ordine di esecuzione: se uso (1) allora posso fare riferimento a add() prima del punto nel codice in cui è definito add(), ma se uso (2) allora devo assegnare la mia funzione a add prima che io possa inizia a fare riferimento a add().

È (1) solo una scorciatoia per (2), anche se uno che si comporta come altri linguaggi in stile C ci consente di definire una funzione "sotto" il punto in cui viene utilizzata? O è internamente un diverso tipo di funzione? Quale è più "nello spirito" di JavaScript (se non è un termine troppo vago)? Vuoi limitare te stesso all'uno o all'altro, e se sì quale?

risposta

6

sembra che si è già a conoscenza delle principali caratteristiche del function declarations (1) e function expressions (2). Si noti inoltre che in (1) v'è ancora una variabile locale chiamata add contenente un valore di funzione, proprio come in (2):

function hello() { 
    alert('Hello World'); 
} 

console.log(typeof hello); // prints "function" 

setTimeout(hello, 1000); // you can still pass functions around as arguments, 
          // even when using function declarations. 

Un altro punto degno di nota è che dichiarazioni di funzione (1) shouldn' Per definire le funzioni in modo condizionale (ad esempio nelle istruzioni if), poiché come già menzionato, vengono automaticamente spostate all'inizio dell'ambito di contenimento dall'interprete JavaScript . Questo è normalmente indicato come hoisting.

Per quanto riguarda quale approccio è più nello spirito di JavaScript, preferisco usare le espressioni di funzione (2). Per un parere più autorevole, Douglas Crockford elenca le dichiarazioni di funzione (1) nel capitolo "Parti errate" nel suo popolare The Good Parts book .


conosciuto anche come dichiarazioni di funzione (Vedi @Tim Down's commenti qui sotto).
In realtà alcuni browser sono in grado di gestire le dichiarazioni di funzione nelle dichiarazioni if (fare sempre riferimento ai commenti di seguito).
JavaScript: The Good Parts - Appendice B: Pagina 113.

+2

Una dichiarazione di funzione all'interno del blocco di un'istruzione 'if' è un errore di sintassi, secondo le specifiche ECMAScript. Nessuno dei principali browser genera un errore, probabilmente a causa del precedente impostato da IE e Mozilla. Mozilla lo aggira includendo un'estensione di ECMAScript chiamata 'FunctionStatement' (http://www.jibbering.com/faq/#functionStatement, http://kangax.github.com/nfe/#function-statements). JScript ha meno rispetto per le specifiche e conosce Dio internamente. –

+1

Un commento sulla modifica: è vero che le dichiarazioni di funzione vengono anche chiamate istruzioni di funzione, ma in modo errato. La FAQ comp.lang.javascript (legato al mio commento precedente) rende questo punto molto eloquente: * "La dichiarazione termine funzione è stato ampiamente ed erroneamente usato per descrivere un' FunctionDeclaration'.This è fuorviante perché in ECMAScript, un 'FunctionDeclaration 'non è un' Statement'; ci sono dei posti in un programma in cui un 'Statement' è permesso ma un' FunctionDeclaration' non lo è. "* –

+0

@Tim: Grazie per i commenti interessanti. Non ero a conoscenza del problema di denominazione "statement". –

2
function foo() {}; 
foo.toString() //-> "function foo() {}" 

var bar = foo; 
bar.toString() //-> "function foo() {}" 

Così dichiara una funzione denominata. Indipendentemente da quali punti variabili, il nome viene mantenuto.L'uso dell'altra sintassi è una funzione anonima, che è senza nome e può essere raggiunta solo se viene fatta riferimento a una variabile.

var foo = function() {}; 
foo.toString() //-> "function() {}" 

var bar = foo; 
bar.toString() //-> "function() {}" 

Per quanto riguarda lo stile da usare, non v'è alcuna regola importante. Anche se personalmente preferisco la sintassi anonima in quanto mi ricorda che le funzioni sono effettivamente oggetti che possono essere passati in giro. Tendo anche a favorire l'approccio "è tutto in un grande oggetto principale", che richiede che le funzioni vengano dichiarate in questo modo.

var MyThingy = { 
    foo: function() { alert('foo') }, 
    bar: function() { MyThingy.foo() } 
} 

Ma dopo aver creato le funzioni, le differenze non sono veramente importanti e si comportano allo stesso modo. Ma la sintassi anonima ha meno magia di quella scansione che hai citato, e ci sono meno errori nel codice complesso e strane situazioni di scoping.

Problemi correlati