web-dev-qa-db-fra.com

Déclarer des fonctions en JavaScript

Duplicate possible:
Javascript: var functionName = function () {} vs function functionName () {}

Quelle est la différence entre ces deux manières de déclarer une fonction?

function someFunc() { ... }

var someFunc = function() { ... }

Je ne demande pas dans le sens technique. Je ne demande pas ce qui est meilleur pour la lisibilité, ou quel style est préféré.

88
nicholaides

Je suis d'un avis différent avec la plupart des gens ici. Techniquement, cette syntaxe peut signifier la même chose pour déclarer des fonctions dans les deux sens (Je me trompe sur ma dernière déclaration. J'ai lu sur un message diff pourquoi ils sont techniquement diff et j'ajouterai à la fin, pourquoi); mais la façon dont ils jouent un rôle dans l'évolution des schémas est énorme. Je recommande vivement "Javascript: The Good Parts" de Doughlas Crockford.

Mais pour prouver mon propos d'une manière subtile et simple; voici un petit exemple.

//Global function existing to serve everyone
function swearOutLoud(swearWord) {
    alert("You "+ swearWord);           
}
//global functions' territory ends here

//here is mr. spongebob. He is very passionate about his objects; but he's a bit rude.
var spongeBob = {
    name : "squarePants",
    swear : function(swearWord) {
                name = "spongy";
                alert("You "+ swearWord);
                return this;
            }
}

//finally spongebob learns good manners too. EVOLUTION!
spongeBob.apologize = function() {
    alert("Hey " + this.name + ", I'm sorry man!");
    return this;
}


//Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!)
alert(spongeBob.swear("twit").apologize());

si vous regardez le code ci-dessus, j'ai déclaré une fonction avec le nom swearOutLoud. Ce qui prendrait un gros mot de n'importe quel objet ou appel et vous donnera la sortie. Il peut effectuer des opérations sur n’importe quel objet en utilisant le paramètre "this" qui lui est transmis et les arguments.

Cependant, la deuxième déclaration est déclarée comme un attribut d'objet appelé "spongeBob". Ceci est important à noter; comme ici, je me dirige vers un comportement orienté objet. Bien que je maintienne également "l'effet en cascade", je renvoie "ceci" si je n'ai rien d'autre à renvoyer.

Quelque chose de semblable est fait dans jQuery; et ce motif en cascade est important si vous essayez d'écrire un cadre ou quelque chose. Vous allez également le lier au modèle de conception Builder.

Mais avec les fonctions déclarées comme attributs d'un objet, je suis capable d'obtenir un comportement centré sur l'objet qui conduit à un meilleur paradigme de programmation. Sauf si bien conçu; Les fonctions individuelles déclarées à l'extérieur avec un accès global mènent à un mode de codage non orienté objet. Je préfère en quelque sorte le dernier.

Pour voir l'effet en cascade effectif, regardez la dernière déclaration où vous pouvez demander à spongebob de jurer et de présenter ses excuses à la fois. même si excuser a été ajouté ultérieurement comme attribut.

J'espère que mon point est clair. La différence d'un point de vue technique peut être petite; mais du point de vue de la conception et de l’évolution du code, c’est énorme et fait toute la différence.

Mais c'est juste moi! À prendre ou a laisser. :)

EDIT:

Les deux appels sont donc techniquement différents. car une déclaration nommée est liée à un espace de noms global et est définie au moment de l'analyse. Donc, peut être appelé avant même que la fonction soit déclarée.

 //success
 swearOutLoud("Damn");

function swearOutLoud(swearWord) {
    alert("You " + swearWord)
}

Le code ci-dessus fonctionnera correctement. Mais le code ci-dessous ne sera pas.

swear("Damn!");
    var swear = function(swearWord) {
    console.log(swearWord);
}
48
Priyank

Un des avantages de l'utilisation de function someFunc() { ... } est que le nom de la fonction apparaît dans le débogueur Firebug. Les fonctions qui sont déclarées dans l'autre sens (var someFunc = function() { ... }) apparaissent sous la forme anonyme.

14
Igor Zevaka

En réalité, la différence est que la deuxième déclaration nous donne la possibilité de déclarer des fonctions comme celle-ci, ce qui permet d'avoir une fonction en tant que propriété d'un objet:

var myObject=new Object();
myObject.someFunc=function() { ... }; 
5
Soufiane Hassou

En ce qui concerne le style, le deuxième exemple est plus cohérent avec les autres méthodes courantes de déclaration de fonctions et, par conséquent, pourrait être considéré comme plus lisible.

this.someFunc = function() { ... }
...
someFunc: function() { ... },

Cependant, comme mentionné également, il est anonyme et par conséquent, le nom n'apparaît pas lors du profilage. Une autre façon de déclarer la fonction est la suivante, qui vous procure le meilleur des deux mondes.

var someFunc = function someFunc() { ... }
5
frglps

Il est à la fois vrai que la première forme:

function test() { }

est une syntaxe plus reconnue et que la seconde forme:

var test = function() { ... }

vous permet de contrôler l'étendue de la fonction (en utilisant var; sans elle, ce serait de toute façon global).

Et vous pouvez même faire les deux:

var test = function test() { ... test(); ... }

Cela vous permet de définir une fonction récursive dans le second formulaire.

2
EMK

Une autre différence est que, sur la plupart des navigateurs, ce dernier vous permet de définir différentes implémentations en fonction des circonstances, contrairement à l'ancien. Supposons que vous souhaitiez un abonnement aux événements entre navigateurs Si vous avez essayé de définir une fonction addEventListenerTo ainsi:

if (document.addEventListener) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else if (document.attachEvent) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else {
    function addEventListenerTo(target, event, listener) {
        ....
    }
}

sur certains navigateurs, toutes les fonctions finissent par être analysées, la dernière prenant la priorité. Résultat: ce qui précède ne fonctionne tout simplement pas. L'attribution de fonctions anonymes à des variables fonctionnera cependant. Vous pouvez également appliquer des techniques fonctionnelles et basiques programmation orientée aspect utilisant des fonctions anonymes affectées à des variables.

var fib = memoize(function (n) { 
    if (n < 0) return 0;
    if (n < 2) return 1;
    return fib(n-1) + fib(n-2); 
});

...
// patch the $ library function
if (...) {
    $ = around($, fixArg, fixResult);
}
2
outis

Pour la lisibilité, je dirais que le premier est clairement meilleur. Un futur programmeur de maintenance, même en supposant qu'il soit suffisamment familiarisé avec javascript pour connaître la plupart des points plus précis abordés dans ce fil, assumera le premier format.

Par exemple, s'ils veulent un jour ctrl-f pour rechercher la définition de votre fonction afin de voir ce qui s'y passe, vont-ils d'abord rechercher someFunc = function() ou function someFunc() ?

En outre, pour être parfaitement typographiques à ce sujet (puisque nous parlons de lisibilité), les lecteurs numérisent souvent le texte rapidement et seraient plus enclins à sauter une ligne commençant par "var" s’ils recherchent une définition de fonction.

Je sais que c'est une réponse non technique, mais il est plus difficile pour les humains de lire le code que les ordinateurs.

1
Paul Degnan

Quand tu écris

function Test() {
}

JavaScript est en train de créer une propriété à laquelle il affecte l'objet fonction qui, une fois appelé, exécutera le code indiqué dans la définition de la fonction. La propriété est attachée à l'objet window ou à l'objet contenant la définition de la fonction.

1
kiamlaluno