Maison >interface Web >js tutoriel >Une brève analyse de la différence entre la déclaration de fonction et l'expression de fonction dans les compétences JavaScript_javascript

Une brève analyse de la différence entre la déclaration de fonction et l'expression de fonction dans les compétences JavaScript_javascript

WBOY
WBOYoriginal
2016-05-16 16:07:261099parcourir

Je me souviens que lors d'un entretien en tant que stagiaire chez Tencent, l'intervieweur m'a posé cette question.

Copier le code Le code est le suivant :

//Quelle est la différence entre les deux méthodes de déclaration suivantes

fonction foo(){};

var bar = fonction foo(){}; 

Au début, je ne connaissais que deux méthodes de déclaration : la déclaration de fonction et l'expression de fonction. Je ne pouvais pas expliquer les différences spécifiques. Il m'est arrivé de voir récemment un livre sur ce sujet et je voulais le résumer.

Dans ECMAScript, il existe deux méthodes les plus couramment utilisées pour créer des objets fonction, à savoir l'utilisation d'expressions de fonction ou l'utilisation de déclarations de fonction. À cet égard, la spécification ECMAScript indique clairement que la déclaration de fonction doit toujours avoir un identifiant (Identifier), qui est ce que nous appelons le nom de la fonction, et que l'expression de la fonction peut être omise.

Déclaration de fonction :

Copier le code Le code est le suivant :

Identificateur de fonction (FormalParameterList opt){ FunctionBody }

Le processus d'analyse de la déclaration de fonction est le suivant :

 1. Créez un nouvel objet Function, FormalParameterList spécifie les paramètres et FunctionBody spécifie le corps de la fonction. Utilise la chaîne de portées dans l'environnement en cours d'exécution comme portée.

 2. Créez un attribut nommé Identifiant pour l'objet variable actuel, avec la valeur Result(1).

Expression de fonction :

(Les expressions de fonction sont divisées en expressions de fonction anonymes et nommées)

Copier le code Le code est le suivant :

function Identifier opt(FormalParameterList opt){ FunctionBody } //Voici l'expression de fonction nommée

Le processus d'analyse des expressions de fonctions nommées est le suivant :

1. Créer un nouvel objet
2. Ajoutez Result(1) en haut de la chaîne de portée
3. Créez un nouvel objet Function, spécifiez les paramètres dans FormalParameterList et spécifiez le corps de la fonction dans FunctionBody. Utilise la chaîne de portées dans l'environnement d'exécution en cours d'exécution comme portée.
4. Créez un attribut nommé Identifiant pour Result(1), sa valeur est Result(3), en lecture seule, ne peut pas être supprimé
5. Supprimez Result(1)
de la chaîne de portée 6. Retour du résultat (3)

La documentation officielle est très difficile à lire. En termes simples, ECMAScript distingue les deux selon le contexte : si la fonction foo(){} fait partie d'une expression d'affectation, elle est considérée comme une expression de fonction. Et si la fonction foo(){} est contenue dans le corps d'une fonction ou est située dans (le niveau supérieur du) programme, elle est analysée comme une déclaration de fonction. Bien évidemment, lorsque l'identifiant est omis, « l'expression » ne peut être qu'une expression.

Copier le code Le code est le suivant :

function foo(){}; // Déclaration car elle fait partie du programme

var bar = function foo(){}; // Expression, car elle fait partie de l'expression d'affectation (AssignmentExpression)

new function bar(){}; // Expression, car elle fait partie de New expression (NewExpression)

(fonction(){
Function bar(){}; // Déclaration, car elle fait partie du corps de la fonction (FunctionBody)
})();

Il existe une autre situation :

Copier le code Le code est le suivant :

(fonction foo(){})

Ce cas est également une expression de fonction, qui est une fonction entourée d'une paire de parenthèses, () constitue un opérateur de regroupement, et l'opérateur de regroupement ne peut contenir que des expressions.

Copier le code Le code est le suivant :
function foo(){}; // Déclaration de fonction

(function foo(){}); // Expression de fonction : notez qu'elle est incluse dans l'opérateur de regroupement

essayez {
(var x = 5); // Les opérateurs de regroupement ne peuvent contenir que des expressions, pas des instructions (var voici une instruction)
>
attraper (erreur) {
// SyntaxError (car "var x = 5" est une instruction, pas une expression - l'évaluation d'une expression doit renvoyer une valeur, mais l'évaluation d'une instruction ne renvoie pas nécessairement une valeur. - Traduction
>

Parlons brièvement des similitudes et des différences entre les déclarations de fonction et les expressions de fonction. Il existe une différence subtile mais importante dans le comportement des déclarations et des expressions.

Tout d'abord, les déclarations de fonction sont analysées et évaluées avant que les expressions ne soient analysées et évaluées. Même si la déclaration est la dernière ligne du code source, elle sera évaluée avant la première expression dans la même portée. C'est plus facile à comprendre en regardant un exemple. Dans l'exemple suivant, la fonction fn est déclarée après alerte. Cependant, lorsque l'alerte est exécutée, fn est déjà défini :

Copier le code Le code est le suivant :

alert(fn()); //Sortie Helloworld

fonction fn() {
retournez « Helloworld ! » ;
>


Pour résumer brièvement, quelle est la différence ?

1. Les déclarations sont toujours analysées au début de la portée
2. Les expressions sont évaluées uniquement lorsqu'elles sont rencontrées.

La déclaration de fonction a une autre caractéristique importante, c'est-à-dire que le comportement de contrôle de la déclaration de fonction via des instructions conditionnelles n'est pas standardisé, donc différents résultats peuvent être obtenus dans différents environnements. C'est à dire :

Copier le code Le code est le suivant :

// Ne fais jamais ça !
// Différents navigateurs renverront des résultats différents,

si (vrai) {
fonction foo() {
renvoie 'premier' ;
>
>
sinon {
fonction foo() {
renvoie 'seconde' ;
>
>
foo();


// Pensez à utiliser des expressions de fonction dans ce cas :
var foo;
si (vrai) {
foo = fonction() {
renvoie 'premier' ;
};
>
sinon {
foo = fonction() {
renvoie 'seconde' ;
};
>
foo();

Alors, quelles sont les règles réelles d'utilisation des déclarations de fonctions ?

FunctionDeclaration ne peut apparaître que dans Program ou FunctionBody. Syntaxiquement, ils ne peuvent pas apparaître à l'intérieur d'un bloc ({ ... }), par exemple dans une instruction if, while ou for. Parce que Block ne peut contenir que des Statement, mais pas des SourceElement tels que FunctionDeclaration.

D'un autre côté, si vous regardez de plus près les règles de génération, vous constaterez que la seule façon pour une Expression d'apparaître dans un Block est de l'intégrer à un ExpressionStatement. Cependant, la spécification indique clairement que ExpressionStatement ne peut pas commencer par le mot-clé function. Cela signifie en réalité que FunctionExpression ne peut pas apparaître dans Statement ou Block (n'oubliez pas que Block est composé de Statement).

En raison des restrictions ci-dessus, chaque fois qu'une fonction apparaît dans un bloc (comme dans l'exemple ci-dessus), elle doit en fait être traitée comme une erreur de syntaxe plutôt que comme une déclaration ou une expression de fonction.

 

 Alors, quand devrions-nous utiliser des déclarations de fonction ou des expressions de fonction ? Les déclarations de fonction ne peuvent apparaître que dans le « code de programme », ce qui signifie qu'elles ne peuvent apparaître que dans d'autres corps de fonction ou dans l'espace global ; leurs définitions ne peuvent pas être affectées à une variable ou à un attribut, ni transmises en tant que paramètre dans un appel de fonction ; Un exemple est l'utilisation autorisée des déclarations de fonction. foo(), bar() et local() sont toutes déclarées via le mode de déclaration de fonction :

Copier le code Le code est le suivant :

//Environnement mondial
fonction foo() {}

fonction locale() {
// Environnement local
Barre de fonctions() {}
         barre de retour ;
>

Lorsque vous ne pouvez pas utiliser syntaxiquement une déclaration de fonction, vous pouvez utiliser une expression de fonction. Par exemple : passer une fonction en paramètre ou définir une fonction dans un objet littéral :


Copier le code Le code est le suivant :

// Ceci est une expression de fonction anonyme
appelle-moi (fonction () {

//Passer une fonction en paramètre
});

// Ceci est une expression de fonction nommée
appelle-moi(fonctionne-moi() {

// Passe une fonction en paramètre, le nom de la fonction est moi
});

// Autres expressions de fonction
var monobjet = {
Dites : function() {

// Je suis une expression de fonction
}
};

Mes connaissances sont limitées, merci de me corriger s'il y a des erreurs.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn