Dichiarazione di funzione come var anziché funzione


28

Sempre più vedo che le funzioni vengono dichiarate come

var foo = function() {

    // things
};

Invece di come avevo imparato, mi piace

function foo() {

    // things
}

Qual è la differenza? Prestazioni migliori? Scopo? Dovrei usare questo metodo?


vale la pena notare che in javascript, le funzioni sono cittadini di prima classe . Questo ti consente di passare il comportamento proprio come gli oggetti. Questo è molto utile per callback e deleghe, tra le altre cose.
Chris Bye,

Ambito di applicazione . Il wrapping del nome variabile "// cose" sta essenzialmente / si spera impedendo collisioni di nomi delle "// cose" che sta avvolgendo, con altri JavaScript (file) inclusi. Un altro modo di pensarci è che hai creato uno spazio dei nomi "pippo".
radarbob,

Risposte:


25

var foo = function() {} definisce una variabile che fa riferimento a una funzione anonima.

function foo() {}definisce una funzione denominata foo.

Entrambi possono essere passati per nome come parametri di funzione e possono essere istanziati se l'uso previsto è per OOP.

Alla fine della giornata, quello che usi è in gran parte dettato dal tuo caso d'uso specifico (Javascript è divertente così;)). Se finisci per usare il primo, ti consiglio vivamente di nominare la funzione:

var foo = function MY_function() {}. Questa convenzione di denominazione consente al callstack del debugger di non essere inutile.


1
Ci sono andato un po 'lì sulla funzione () MY ...
Erik Reppen il

1
@Demian Brecht, e che dire dell'approccio var foo = function foo () {...}?
shabunc,

@shabunc: che ne pensi? È elencato nell'ultimo paragrafo della mia risposta.
Demian Brecht,

@Demian Brecht, no, in realtà nell'ultimo paragrafo viene chiamato fooe la funzione viene chiamataMY_function
shabunc

@shabunc: il nome non ha importanza. Ciò che conta è il valore nel callstack. Ad esempio, [NAMESPACE] _ [nome fn] è la convenzione utilizzata da Mozilla. Il nome stesso non ha importanza fino a quando la convenzione è coerente in tutto il progetto.
Demian Brecht,

13

espressione di funzione:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

L'espressione func in questo caso è anonima ma assegnata a var per riferimento. Ciò è diverso da un'istruzione di funzione etichettata nei seguenti modi:

  • non può essere sollevato (chiamato prima che sia definito)
  • new someFunction().constructor.name === 'someFunction';//false le istanze non ottengono il nome var per constructor.name perché un riferimento alla funzione è assegnato a var ma var, non la funzione, è legato al nome var

In un'istruzione di funzione etichettata:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • lavori di sollevamento
  • new someFunction().constructor.name === 'someFunction'; //true il nome è legato direttamente alla funzione.

In generale, non esiste davvero alcun motivo valido per fare espressione su var a meno che non si desideri che le chiamate falliscano se le cose vengono spostate o si sta definendo / assegnando un metodo su una riga. In realtà trovo utile il sollevamento per organizzare gli oggetti con definizioni interne di funzioni e metodi nella parte inferiore in modo da poter arrivare al comportamento reale dell'oggetto e fare definizioni di metodi pubblici di una riga (assegnando semplicemente funzioni a this.con lo stesso nome) tutto in uno spot per facilità di riferimento. Dovresti sempre provare a usare le istruzioni etichettate per i costruttori, IMO, in modo da poter identificare il 'tipo' di un oggetto tramite il suo costruttore.


8

Il tuo primo esempio è un'espressione mentre il secondo esempio è un'istruzione . La definizione di funzioni come espressioni consente una maggiore flessibilità in cui può verificarsi la definizione, a cosa è possibile assegnarla, che è possibile passarla come parametro, ecc.

Per esempio:

SomeThing('abc', function(a,b) {return a*b;});

vs ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

Esempi più complessi diventerebbero oscenamente complicati senza la sintassi dell'espressione della funzione.

Guarda /programming/111102/how-do-javascript-closures-work


4

La principale differenza pratica è il sollevamento. Per esempio:

foo(); // alerts 'hello'
function foo() {alert('hello');}

vs

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Inoltre, questo è un comportamento indefinito

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

mentre questo va bene.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}

7
Non c'è assolutamente nulla di sbagliato nel definire una funzione all'interno di una funzione in JS. Non ci sono molti posti in cui non puoi definire una funzione in JS.
Erik Reppen,

2
@ErikReppen Non puoi assolutamente usare dichiarazioni di funzioni all'interno di blocchi non funzionali (come all'interno di un'istruzione if). Non riesco a trovare dove ho letto che non possono essere utilizzati all'interno di un'altra funzione.
Austin,

@Austin Non c'è niente di sbagliato nella definizione di una funzione all'interno di ifun'istruzione!
Tim

@Austin: Forse l'hai letto su w3schools? ;)
Demian Brecht,

2
@ErikReppen Le espressioni di funzione possono essere utilizzate ovunque. Le dichiarazioni di funzione non possono essere. Vedi stackoverflow.com/questions/10069204/…
Austin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.