2010-05-28 4 views
25

Possible en double:
JavaScript: var functionName = function() {} vs function functionName() {}Y a-t-il une différence entre var name = function() {} & function name() {} dans Javascript?

Supposons que nous sommes dans une fonction et non pas dans l'espace de noms global.

function someGlobalFunction() { 
    var utilFunction1 = function() { 
    } 

    function utilFunction2() { 
    } 

    utilFunction1(); 
    utilFunction2(); 

} 

Sont-ils synonymes? Et ces fonctions cessent-elles complètement d'exister quand someGlobalFunction revient? Dois-je préférer l'un ou l'autre pour la lisibilité ou pour une autre raison?

Répondre

46

Ils sont principalement les mêmes.

utilFunction1 ne sera disponible qu'après avoir été déclaré. utilFunction2 est hissé en haut de la fonction, donc peut être utilisé avant qu'il ne soit défini.

function someGlobalFunction() { 
    utilFunction1(); // Error: untilFunction1 is undefined :(
    utilFunction2(); // Works 

    var utilFunction1 = function() { 
    } 

    function utilFunction2() { 
    } 
} 

À moins qu'ils sont pris au piège dans une fermeture, les deux cesseront d'exister lorsque someGlobalFunction retours.

Je préfère utiliser la méthode utilisée pour déclarer utilFunction2, mais c'est à vous de décider.

Déclarations de la forme utilFunction2 (qui sont appelées déclarations de fonction) ont l'avantage d'être nommé (c.-à apparaître comme utilFunction2) dans votre-debugeur préféréTM, où que utilFunction1 (appelées expressions de fonction) serait juste apparaître comme une fonction anonyme .


Pour être complet, vous avez également la forme;

var utilFunction3 = function utilFunction4() { 
    // blah 
}; 

... qui est appelé une expression de fonction nommée, qui a weird properties (et bugs (dans les anciennes versions de IE)) de son propre.

+0

+1 - On dirait que tout est couvert. – ChaosPandion

+3

On peut également noter que le premier est une FunctionExpression tandis que le dernier est une FunctionDeclaration. –

9

Oui, ils sont tout à fait différents:

  • utilFunction1 n'a pas de nom, donc si elle lance une exception, votre outil de débogage ne vous dira qu'une fonction anonyme a jeté
  • utilFunction2 sera disponible en la portée de la fonction avant même que cette ligne est atteinte (comme fletcher noté)
  • en utilisant la notation utilFunction2 peut provoquer un comportement impair dans certaines circonstances dans IE.

Ex:

if (true) { 
    function utilFunction() { 
    return true; 
    } 
} else { 
    function utilFunction() { 
    return false; 
    } 
} 

utilFunction(); // returns false in IE, true everywhere else 

IE prend la question de la portée de fonction aux fonctions extrêmes, l'évaluation efficace, même s'il n'y a pas de chemin de code pour eux!

+7

Mettre une instruction de fonction à l'intérieur d'un bloc «if» ou autre n'est pas valide dans ECMAScript; le comportement du navigateur varie énormément. Éviter! – bobince

8

Félicitations!Vous avez trouvé la situation où Function Hoisting est impliqué.

var foo = function() { }; 

est tout à fait différent de celui

function foo() { }; 

Pour toutes les raisons mentionnées ailleurs, plus un.

Le deuxième exemple sera "hissé" - il sera disponible n'importe où dans la fermeture actuelle (généralement la fonction actuelle). Même avant qu'il ne soit déclaré à l'intérieur de ladite fermeture.

Quelque chose comme ça fonctionnerait:

function foo() { 
    bar(); 
    function bar() { alert('baz'); } 
} 

Alors que quelque chose comme cela certainement pas:

function foo() { 
    bar(); 
    var bar = function bar() { alert('baz'); }; 
} 

Vous obtenez une erreur dans ce second exemple, parce que bar n'a pas été défini encore. Si vous échangez les deux lignes dans la fonction foo, cet exemple fonctionnera.

Douglas Crockford préconise l'utilisation de cette seconde méthode, car elle ne contient pas de comportement caché comme le hissage - votre code fait exactement ce qu'il dit, sans astuces.

Questions connexes