Déclaration de plusieurs variables en JavaScript

334

En JavaScript, il est possible de déclarer plusieurs variables comme ceci:

var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

... ou comme ça:

var variable1 = "Hello World!",
    variable2 = "Testing...",
    variable3 = 42;

Une méthode est-elle meilleure / plus rapide que l'autre?

Steve Harrison
la source
6
Quant à plus rapide , en utilisant ce jsperf, je ne pouvais pas voir un gain de vitesse constant en utilisant une méthode ou l'autre.
Majid Fouladpour

Réponses:

345

La première façon est plus facile à entretenir. Chaque déclaration est une instruction unique sur une seule ligne, vous pouvez donc facilement ajouter, supprimer et réorganiser les déclarations.

Avec la deuxième façon, il est ennuyeux de supprimer la première ou la dernière déclaration car elles contiennent le varmot-clé et le point-virgule. Et chaque fois que vous ajoutez une nouvelle déclaration, vous devez remplacer le point-virgule de l'ancienne ligne par une virgule.

Jeremy Ruten
la source
67
Si vous écrivez du code que vous prévoyez de réduire ou de compresser plus tard, la deuxième façon permet aux compresseurs (comme le compresseur YUI) de vous donner une version plus réduite. Si la taille est une considération, alors je suggérerais de suivre autant de suggestions de JSLint que possible.
Lane
36
jslint affirme que la deuxième voie est plus juste mais je ne suis pas d'accord.
ThatGuy
29
La deuxième voie est une micro-optimisation. Toutes les déclarations var sont traitées en une seule fois, plutôt qu'une à la fois. Cela n'a pas beaucoup d'importance dans les navigateurs / ordinateurs modernes.
webnesto
18
@ 0xc0de: Je voudrais voir la preuve de déclarer toutes les variables dans une instruction comme "efficaces". Si vous ne mesurez l'efficacité qu'en fonction des quelques octets enregistrés, alors peut-être. Mais si vous tenez compte de la lisibilité et de la maintenabilité, je pense que vous constaterez que l'optimisation prématurée est généralement la mauvaise voie à suivre, d'autant plus que les navigateurs modernes collecteront et initialiseront toutes les variables d'une portée lors d'une passe de pré-exécution. Personnellement, je trouve que toutes les variables sont déclarées sur une seule ligne ou instruction pour rendre la compréhension du code plus difficile et plus sujette aux erreurs.
ogradyjd
9
En ce qui concerne l'efficacité, uglifyjs et le compilateur de fermeture Google écraseront automatiquement les instructions var séquentielles en un seul, ce qui rendra ce point théorique (pour autant que je sache, YUI ne le fera pas, mais je n'ai pas testé de manière approfondie).
bhuber
215

Outre la maintenabilité, la première façon élimine la possibilité de création de variables globales accidentelles:

(function () {
var variable1 = "Hello World!" // semicolon is missed out accidently
var variable2 = "Testing..."; // still a local variable
var variable3 = 42;
}());

Alors que la deuxième façon est moins indulgente:

(function () {
var variable1 = "Hello World!" // comma is missed out accidently
    variable2 = "Testing...", // becomes a global variable
    variable3 = 42; // a global variable as well
}());
Kenny Ki
la source
4
Bon point. Si elles sont courtes, puis écrit sur une seule ligne évitera ce problème: var variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;. Un manquant ,va planter, mais je conviens que c'est risqué
Aram Kocharyan
14
Si vous utilisez le mode strict, vous ne pourrez de toute façon pas créer de tels globaux.
Danyal Aytekin
1
Je suis fan de déclarer plusieurs variables sur une seule ligne parce que je pense que cela semble plus propre. Cela dit, déclarer accidentellement des variables globales est un réel danger. En recherchant les fuites de mémoire, je suis tombé sur plusieurs cas où j'ai accidentellement déclaré plusieurs variables globales à la fois parce que j'utilisais un point-virgule au lieu d'une virgule.
smabbott
+1 vient de passer la moitié de la journée et a même commencé à se demander pourquoi il y avait une différence non documentée entre ces deux déclarations. Ensuite, lisez cette réponse, vérifiez le code très attentivement et trouvez l'erreur. Besoin de vacances ...
Giedrius
1
Mon éditeur de texte me donne un Possible Fatal Errorsi je manque un coma, hourra pour moi!
33

Il est courant d'utiliser une varinstruction par étendue pour l'organisation. La façon dont toutes les «étendues» suivent un modèle similaire, ce qui rend le code plus lisible. De plus, le moteur les «hisse» tous au sommet de toute façon. Donc, garder vos déclarations ensemble imite ce qui se passera réellement de plus près.

spencer.sm
la source
6
Vous pouvez conserver les déclarations ensemble sans les faire partager la même déclaration «var». Je comprends et accepte les explications données sur jslint (votre lien) mais je ne partage pas la conclusion. Comme dit plus haut, c'est plus une question de style qu'autre chose. Dans le monde Java (entre autres), l'inverse (une déclaration par ligne) est recommandé pour la lisibilité.
PhiLho
Plus lisible? La seule raison pour laquelle les gens les mettent sur une seule ligne est la raison spécifique à JS que vous avez mentionnée: JS déplace toutes les déclarations vers le haut. Si ce n'était pas le cas, nous déclarerions tous nos vars les plus proches du point où ils sont utilisés.
Danyal Aytekin
@ vol7ron ce n'est pas le cas, et c'est une grave incompréhension de la vardéclaration. l'exact opposé est vrai. voir la documentation et cet exemple
jackweirdy
@jackweirdy vous avez raison et c'était le cas, une mauvaise implémentation ou un bug dans les anciens navigateurs. J'ai depuis supprimé mon commentaire.
vol7ron
29

C'est beaucoup plus lisible lorsque vous le faites de cette façon:

var hey = 23;
var hi = 3;
var howdy 4;

Mais prend moins d'espace et de lignes de code de cette façon:

var hey=23,hi=3,howdy=4;

Il peut être idéal pour économiser de l'espace, mais laissez les compresseurs JavaScript le gérer pour vous.

Jason Stackhouse
la source
15

Peut-être comme ça

var variable1 = "hello world"
, variable2 = 2
, variable3 = "how are you doing"
, variable4 = 42;

Sauf lors du changement de la première ou de la dernière variable, il est facile à maintenir et à lire.

joe nerdan
la source
6
En règle générale, en utilisant virgule en premier, le point-virgule va sur une nouvelle ligne pour éviter ce problème. var variable1 = "bonjour le monde" \ n, variable2 = 2 \ n, variable3 = "comment allez-vous" \ n, variable4 = 42 \ n; \ n
BrianFreud
2
Il s'agit de la syntaxe Haskell. Je pense que ce n'est pas recommandé / pratique courante en javascript
shamanSK
14

C'est juste une question de préférence personnelle. Il n'y a aucune différence entre ces deux façons, à l'exception de quelques octets enregistrés avec le second formulaire si vous supprimez l'espace blanc.

Brian Campbell
la source
Le second enregistre quelques octets.
Sophie Alpert
Ben Alpert: Comment figurez-vous?
Josh Stodola
Si vous supprimez l'espace, alors 'var foo = "hello", bar = "world";' déclaration prend moins de caractères que 'var foo = "hello"; var bar = "world";' Si vous avez un site populaire, économiser quelques octets sur le JS peut vous aider (vous voudriez aussi minimiser les noms de variables, etc.)
Brian Campbell
Je considère que les octets enregistrés ne sont pas pertinents pour le moment, en raison de la montée des minificateurs JavaScript, notamment le mode simple (soi-disant) du compilateur Google Closer.
Bryan Field
1
@webnesto il n'y a jamais de performance de la syntaxe lorsque la sémantique de la syntaxe est la même. On n'exécutera pas le code tout de suite mais d'abord l'analyser et faire une analyse sémantique - c'est là que les deux styles de déclaration sont égalisés.
Esailija
14

ECMAScript6 a introduit une affectation de déstructuration qui fonctionne plutôt bien:

[a, b] = [1, 2] asera égal 1et bsera égal 2.

Nir Naor
la source
il ne répond pas à la question, mais il peut être une meilleure alternative aux deux approches décrites.
svarog
1
Je pense que votre approche n'est pas vraiment viable au cas où vous auriez de longues listes de variables. Il est difficile de dire à quelle variable quelle valeur est liée et vous n'avez pas non plus de protection contre les erreurs en cas de mauvaise fusion pendant laquelle vous pourriez accidentellement supprimer un élément d'un tableau. Exemple: let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; Donc, personnellement, je ne le recommande pas.
Kirill Reznikov
1
pratique si vous souhaitez définir un grand nombre de variables avec les mêmes valeurs. Utiliser pour réinitialiser à zéro dans une boucle par exemple.
Nick
Oui! C'est ce que je cherchais. Surtout si vous souhaitez définir une paire bidimensionnelle ou des valeurs multidimensionnelles, mais pas des tableaux.
Eugene Kardash
11
var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

est plus lisible que:

var variable1 = "Hello World!",
    variable2 = "Testing...",
    variable3 = 42;

Mais ils font la même chose.

Kevin Crowell
la source
Utilise moins "d'espace fichier"? Je pense que vous avez des explications à faire.
Josh Stodola
@JoshStodola me ressemble dans le même espace fichier. Depuis plutôt que var<space>, son<space><space><space><space>
WORMSS
@WORMSS à moins qu'elle soit var<space>ou var<tab>contre <tab>. Toujours largement théorique.
mpag
9

Utilisez l' affectation ES6 Destructuring : il décompactera les valeurs des tableaux ou les propriétés des objets dans des variables distinctes.

let [variable1 , variable2, variable3] = 
["Hello World!", "Testing...", 42];

console.log(variable1); // Hello World!
console.log(variable2); // Testing...
console.log(variable3); // 42

Rohit Jindal
la source
4
C'est une idée terrible, surtout si vous devez affecter environ 10 variables.
Kirill Reznikov
7

Ma seule utilisation, pourtant essentielle, de la virgule est dans une boucle for:

for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}

Je suis allé ici pour vérifier si cela est OK en JavaScript.

Même en le voyant fonctionner, il restait à savoir si n est local à la fonction.

Cela vérifie, n est local:

a=[3,5,7,11];
(function l () { for (var i = 0, n = a.length; i < n; i++) {
  var e = a[i];
  console.log(e);
}}) ();
console.log(typeof n == "undefined" ?
  "as expected, n was local" : "oops, n was global");

Pendant un moment, je n'étais pas sûr de passer d'une langue à l'autre.

codelion
la source
7

Bien que les deux soient valides, l'utilisation de la seconde décourage les développeurs inexpérimentés de placer des instructions var partout et de provoquer des problèmes de levage. S'il n'y a qu'une seule var par fonction, en haut de la fonction, il est plus facile de déboguer le code dans son ensemble. Cela peut signifier que les lignes où les variables sont déclarées ne sont pas aussi explicites que certains le souhaiteront.

Je pense que le compromis en vaut la peine, si cela signifie sevrer un développeur de la suppression de «var» partout où il le souhaite.

Les gens peuvent se plaindre de JSLint, je le fais aussi, mais une grande partie n'est pas destinée à résoudre les problèmes de langage, mais à corriger les mauvaises habitudes des codeurs et donc à prévenir les problèmes dans le code qu'ils écrivent. Par conséquent:

"Dans les langages à portée de bloc, il est généralement recommandé de déclarer les variables sur le site de première utilisation. Mais comme JavaScript n'a pas de portée de bloc, il est plus judicieux de déclarer toutes les variables d'une fonction en haut de la fonction. recommandé d'utiliser une seule instruction var par fonction. " - http://www.jslint.com/lint.html#scope

Wade Harrell
la source
6

Je pense que c'est une question de préférence personnelle. Je préfère le faire de la manière suivante:

   var /* Vars */
            me = this, that = scope,
            temp, tempUri, tempUrl,
            videoId = getQueryString()["id"],
            host = location.protocol + '//' + location.host,
            baseUrl = "localhost",
            str = "Visit W3Schools",
            n = str.search(/w3schools/i),
            x = 5,
            y = 6,
            z = x + y
   /* End Vars */;
v1r00z
la source
6

Une autre raison pour éviter la version à instruction unique ( var unique ) est le débogage. Si une exception est levée dans un des lignes d'affectation, la trace de pile n'affiche qu'une seule ligne.

Si vous aviez 10 variables définies avec la syntaxe virgule, vous n'avez aucun moyen de savoir directement laquelle était la coupable.

La version de déclaration individuelle ne souffre pas de cette ambiguïté.

Shawn
la source
2

Le concept de "Cohésion sur Couplage" peut être appliqué plus généralement que de simples objets / modules / fonctions. Il peut également servir dans cette situation:

Le deuxième exemple suggéré par l'OP a couplé toutes les variables dans la même instruction, ce qui rend impossible de prendre une des lignes et de la déplacer ailleurs sans casser des trucs (couplage élevé). Le premier exemple qu'il a donné rend les affectations variables indépendantes les unes des autres (couplage faible).

"Un faible couplage est souvent le signe d'un système informatique bien structuré et d'une bonne conception, et lorsqu'il est combiné à une cohésion élevée, il soutient les objectifs généraux de haute lisibilité et maintenabilité."

http://en.wikipedia.org/wiki/Coupling_(computer_programming)

Alors choisissez le premier.

Magne
la source
1
Je ne vois pas comment cela est lié au couplage ou à la cohésion. Envie d'élaborer?
Edson Medina
Le deuxième exemple suggéré par l'OP a couplé toutes les variables dans la même instruction, ce qui rend impossible de prendre une des lignes et de la déplacer ailleurs sans casser des trucs (couplage élevé). Le premier exemple qu'il a donné rend les affectations variables indépendantes les unes des autres (couplage faible).
Magne
Le couplage concerne l'interdépendance entre différents modules / objets / fonctions, PAS des lignes de code!
Edson Medina
1
À l'origine, il s'agissait de modules, oui, mais le concept peut être appliqué de manière plus générale, comme le montre même votre propre inclusion d'objets / fonctions dans la définition.
Magne
2

Un vieux post, je sais, mais pour ajouter un petit détail de perspective pour les autres Googleurs:

Le problème de maintenabilité peut être assez facilement résolu avec un peu de mise en forme, comme tel.

let
  my_var1 = 'foo',
  my_var2 = 'bar',
  my_var3 = 'baz'
;

J'utilise cette mise en forme uniquement par préférence personnelle. Je saute ce format pour les déclarations simples, bien sûr, ou où cela résume simplement les travaux.

Beau
la source
1

Je crois qu'avant de commencer à utiliser ES6, l'approche avec une seule déclaration var n'était ni bonne ni mauvaise (dans le cas où vous avez des linters et 'use strict'. C'était vraiment une préférence gustative. Mais maintenant les choses ont changé pour moi. Mes pensées sont en faveur de la déclaration multiligne :

  1. Nous avons maintenant deux nouveaux types de variables et nous sommes vardevenus obsolètes. Il est recommandé de l'utiliser constpartout où vous en avez vraiment besoin let. Donc, très souvent, votre code contiendra des déclarations de variables avec une affectation au milieu du code, et en raison de la portée des blocs, vous déplacerez assez souvent des variables entre les blocs en cas de petits changements. Je pense qu'il est plus pratique de le faire avec des déclarations multilignes.

  2. La syntaxe ES6 est devenue plus diversifiée, nous avons obtenu des destructeurs, des chaînes de modèle, des fonctions fléchées et des affectations facultatives. Lorsque vous utilisez fortement toutes ces fonctionnalités avec des déclarations var simples, cela nuit à la lisibilité.

Kirill Reznikov
la source
0

Je pense que la première façon (plusieurs vars) est la meilleure, car vous pouvez sinon vous retrouver avec cela (à partir d'une application qui utilise Knockout), qui est difficile à lire à mon avis:

    var categories = ko.observableArray(),
        keywordFilter = ko.observableArray(),
        omniFilter = ko.observable('').extend({ throttle: 300 }),
        filteredCategories = ko.computed(function () {
            var underlyingArray = categories();
            return ko.utils.arrayFilter(underlyingArray, function (n) {
                return n.FilteredSportCount() > 0;
            });
        }),
        favoriteSports = ko.computed(function () {
            var sports = ko.observableArray();
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        sports.push(a);
                    }
                });
            });
            return sports;
        }),
        toggleFavorite = function (sport, userId) {
            var isFavorite = sport.IsFavorite();

            var url = setfavouritesurl;

            var data = {
                userId: userId,
                sportId: sport.Id(),
                isFavourite: !isFavorite
            };

            var callback = function () {
                sport.IsFavorite(!isFavorite);
            };

            jQuery.support.cors = true;
            jQuery.ajax({
                url: url,
                type: "GET",
                data: data,
                success: callback
            });
        },
        hasfavoriteSports = ko.computed(function () {
            var result = false;
            ko.utils.arrayForEach(categories(), function (c) {
                ko.utils.arrayForEach(c.Sports(), function (a) {
                    if (a.IsFavorite()) {
                        result = true;
                    }
                });
            });
            return result;
        });
vegemite4me
la source