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.