Deklarieren mehrerer Variablen in JavaScript

333

In JavaScript können mehrere Variablen wie folgt deklariert werden:

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

... oder so:

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

Ist eine Methode besser / schneller als die andere?

Steve Harrison
quelle
6
Was schneller , mit diesen jsperf konnte ich nicht eine einheitliche Geschwindigkeitsverstärkung mit einer bestimmten Methode oder das andere sehen.
Majid Fouladpour

Antworten:

344

Der erste Weg ist einfacher zu warten. Jede Deklaration ist eine einzelne Anweisung in einer einzelnen Zeile, sodass Sie die Deklarationen einfach hinzufügen, entfernen und neu anordnen können.

Beim zweiten Weg ist es ärgerlich, die erste oder letzte Deklaration zu entfernen, da sie das varSchlüsselwort und das Semikolon enthalten. Und jedes Mal, wenn Sie eine neue Deklaration hinzufügen, müssen Sie das Semikolon in der alten Zeile in ein Komma ändern.

Jeremy Ruten
quelle
67
Wenn Sie Code schreiben, den Sie voraussichtlich minimieren oder später packen werden, können Kompressoren (wie der YUI-Kompressor) auf die zweite Weise eine verkleinerte Version erhalten. Wenn die Größe eine Rolle spielt, würde ich vorschlagen, möglichst vielen Vorschlägen von JSLint zu folgen.
Lane
36
jslint behauptet, der zweite Weg sei gerechter, aber ich bin anderer Meinung.
ThatGuy
29
Der zweite Weg ist eine Mikrooptimierung. Alle var-Deklarationen werden auf einmal und nicht einzeln verarbeitet. Dies ist in modernen Browsern / modernen Computern nicht so wichtig.
Webnesto
18
@ 0xc0de: Ich würde gerne den Beweis sehen, dass alle Variablen in einer Anweisung als "effizient" deklariert werden. Wenn Sie die Effizienz nur anhand der wenigen gespeicherten Bytes messen, dann vielleicht. Wenn Sie jedoch die Lesbarkeit und Wartbarkeit berücksichtigen, werden Sie feststellen, dass eine vorzeitige Optimierung normalerweise der falsche Weg ist, zumal moderne Browser alle Variablen in einem Bereich in einem Durchlauf vor der Ausführung erfassen und initialisieren. Persönlich finde ich, dass Variablen alle in einer einzigen Zeile oder Anweisung deklariert sind, um das schnelle Verständnis von Code schwieriger und fehleranfälliger zu machen.
ogradyjd
9
In Bezug auf die Effizienz werden sowohl uglifyjs als auch der Google Closure Compiler automatisch sequentielle var-Anweisungen zu einer zusammenfassen, wodurch dieser Punkt in Frage gestellt wird (soweit ich sagen kann, wird YUI dies nicht tun, ich habe es jedoch nicht ausführlich getestet).
Bhuber
215

Neben der Wartbarkeit schließt der erste Weg die Möglichkeit der Erstellung globaler Unfallvariablen aus:

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

Während der zweite Weg weniger verzeihend ist:

(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
quelle
4
Guter Punkt. Wenn sie kurz sind, wird durch Schreiben in einer einzelnen Zeile das folgende Problem vermieden : var variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;. Ein Vermisster ,wird abstürzen, aber ich stimme zu, dass es riskant ist
Aram Kocharyan
14
Wenn Sie den strengen Modus verwenden, können Sie solche Globals sowieso nicht erstellen.
Danyal Aytekin
1
Ich bin ein Fan davon, mehrere Variablen in einer einzigen Zeile zu deklarieren, weil ich denke, dass es sauberer aussieht. Das versehentliche Deklarieren globaler Variablen ist jedoch eine echte Gefahr. Bei der Suche nach Speicherlecks bin ich auf mehrere Fälle gestoßen, in denen ich versehentlich mehrere globale Variablen gleichzeitig deklariert habe, weil ich ein Semikolon anstelle eines Kommas verwendet habe.
Smabbott
+1 verbrachte nur die Hälfte des Tages und begann sich sogar zu fragen, warum es einen undokumentierten Unterschied zwischen diesen beiden Erklärungen gibt. Dann lesen Sie diese Antwort, überprüfen Sie den Code sehr sorgfältig und finden Sie den Fehler. Brauchen Sie einen Urlaub ...
Giedrius
1
Mein Texteditor gibt mir ein, Possible Fatal Errorwenn ich ein Koma verpasse, Hurra für mich!
33

Es ist üblich, eine varAnweisung pro Bereich für die Organisation zu verwenden. Die Art und Weise, wie alle "Bereiche" einem ähnlichen Muster folgen, macht den Code besser lesbar. Außerdem "hebt" der Motor sie sowieso alle nach oben. Wenn Sie also Ihre Erklärungen zusammenhalten, ahmen Sie nach, was tatsächlich genauer passieren wird.

spencer.sm
quelle
6
Sie können die Deklarationen zusammenhalten, ohne dass sie dieselbe 'var'-Deklaration verwenden. Ich verstehe und akzeptiere die Erklärungen bei jslint (Ihr Link), aber ich teile die Schlussfolgerung nicht. Wie oben gesagt, ist es mehr eine Frage des Stils als alles andere. In der Java-Welt (unter anderem) wird aus Gründen der Lesbarkeit die Umkehrung (eine Deklaration pro Zeile) empfohlen.
PhiLho
Besser lesbar? Der einzige Grund, warum Leute sie in eine Zeile setzen, ist der von Ihnen erwähnte JS-spezifische Grund: JS verschiebt alle Deklarationen nach oben. Wenn dies nicht der Fall wäre, würden wir alle unsere Vars am nächsten an dem Punkt deklarieren, an dem sie verwendet werden.
Danyal Aytekin
@ vol7ron das ist nicht der Fall und ist ein grobes Missverständnis der varAussage. Das genaue Gegenteil ist der Fall. Siehe die Dokumentation und dieses Beispiel
Jackweirdy
@jackweirdy Sie haben Recht und es war der Fall, schlechte Implementierung oder Fehler in älteren Browsern. Ich habe seitdem meinen Kommentar gelöscht.
Vol7ron
29

Es ist viel besser lesbar, wenn Sie es so machen:

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

Benötigt aber weniger Platz und Codezeilen auf diese Weise:

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

Es kann ideal sein, um Platz zu sparen, aber lassen Sie JavaScript-Kompressoren dies für Sie erledigen.

Jason Stackhouse
quelle
15

Vielleicht so

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

Außer beim Ändern der ersten oder letzten Variablen ist es einfach zu pflegen und zu lesen.

Joe Nerdan
quelle
6
Bei Verwendung von Komma zuerst wird das Semikolon normalerweise in eine neue Zeile eingefügt, um dieses Problem zu vermeiden. var variable1 = "Hallo Welt" \ n, Variable2 = 2 \ n, Variable3 = "Wie geht es dir
?
2
Dies ist die Haskell-Syntax. Ich fühle, dass es irgendwie nicht empfohlen / übliche Praxis in Javascript
shamanSK
14

Es ist nur eine Frage der persönlichen Präferenz. Es gibt keinen Unterschied zwischen diesen beiden Möglichkeiten, abgesehen von einigen Bytes, die mit dem zweiten Formular gespeichert wurden, wenn Sie den Leerraum entfernen.

Brian Campbell
quelle
Der zweite spart ein paar Bytes.
Sophie Alpert
Ben Alpert: Wie denkst du?
Josh Stodola
Wenn Sie das Leerzeichen entfernen, wird 'var foo = "Hallo", bar = "Welt";' Die Deklaration nimmt weniger Zeichen ein als 'var foo = "Hallo"; var bar = "Welt";' Wenn Sie eine beliebte Site haben, kann das Speichern einiger Bytes auf dem JS hilfreich sein (Sie möchten auch Variablennamen usw. minimieren)
Brian Campbell
Ich sehe die gespeicherten Bytes derzeit als irrelevant an, da JavaScript-Minifiers aufkommen, insbesondere der (sogenannte) einfache Modus des Google Closer Compilers.
Bryan Field
1
@webnesto Es gibt keine Leistung von Syntax, wenn die Semantik der Syntax gleich ist. Man wird Code nicht sofort ausführen, sondern zuerst analysieren und eine semantische Analyse durchführen - hier werden beide Deklarationsstile ausgeglichen.
Esailija
14

ECMAScript6 hat eine Destrukturierungszuweisung eingeführt, die ziemlich gut funktioniert:

[a, b] = [1, 2] awird gleich 1und bwird gleich 2.

Nir Naor
quelle
es beantwortet die Frage nicht, kann aber eine bessere Alternative zu beiden beschriebenen Ansätzen sein.
Svarog
1
Ich denke, dass Ihr Ansatz nicht wirklich praktikabel ist, wenn Sie lange Listen von Variablen haben. Es ist schwer zu sagen, auf welche Variable welcher Wert sich bezieht, und Sie haben auch keinen Schutz vor Fehlern. Dies ist der Fall einer fehlerhaften Zusammenführung, bei der Sie versehentlich ein Element aus einem Array entfernen könnten. Beispiel: let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; Ich persönlich empfehle es also nicht.
Kirill Reznikov
1
Praktisch, wenn Sie viele Variablen mit denselben Werten festlegen möchten. Zum Beispiel zum Zurücksetzen auf Null in einer Schleife.
Nick
Ja! das habe ich gesucht. Insbesondere, wenn Sie ein zweidimensionales Paar oder mehrdimensionale Werte definieren möchten, jedoch keine Arrays.
Eugene Kardash
11
var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

ist besser lesbar als:

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

Aber sie machen das Gleiche.

Kevin Crowell
quelle
Verbraucht weniger "Dateibereich"? Ich denke, Sie müssen etwas erklären.
Josh Stodola
@JoshStodola sieht für mich genauso aus wie der Dateibereich. Da statt var<space>- es ist<space><space><space><space>
WORMSS
@WORMSS es sei denn , es ist var<space>oder var<tab>vs <tab>. Immer noch weitgehend strittig.
mpag
9

Verwenden Sie ES6 Destrukturierung Zuordnung : Es wird auspacken Werte von Arrays oder Eigenschaften von Objekten in verschiedene Variablen.

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

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

Rohit Jindal
quelle
4
Es ist eine schreckliche Idee, besonders wenn Sie ungefähr 10 Variablen zuweisen müssen.
Kirill Reznikov
7

Meine einzige, aber wesentliche Verwendung für Komma ist eine for-Schleife:

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

Ich habe hier nachgeschlagen, ob dies in JavaScript in Ordnung ist.

Selbst als es funktionierte, blieb die Frage offen, ob n für die Funktion lokal ist.

Dies überprüft, ob n lokal ist:

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");

Für einen Moment war ich mir nicht sicher, ob ich zwischen den Sprachen wechseln sollte.

Codelion
quelle
7

Obwohl beide gültig sind, hält die Verwendung der zweiten Option unerfahrene Entwickler davon ab, überall var-Anweisungen zu platzieren und Probleme beim Heben zu verursachen. Wenn es oben in der Funktion nur eine Variable pro Funktion gibt, ist es einfacher, den Code als Ganzes zu debuggen. Dies kann bedeuten, dass die Zeilen, in denen die Variablen deklariert sind, nicht so explizit sind, wie manche möchten.

Ich bin der Meinung, dass sich ein Kompromiss lohnt, wenn es bedeutet, einen Entwickler davon abzuhalten, "var" überall dort abzulegen, wo er Lust hat.

Die Leute mögen sich auch über JSLint beschweren, aber viele davon zielen nicht darauf ab, Probleme mit der Sprache zu beheben, sondern schlechte Gewohnheiten der Codierer zu korrigieren und damit Probleme im Code, den sie schreiben, zu verhindern. Deshalb:

"In Sprachen mit Blockbereich wird normalerweise empfohlen, Variablen an der Stelle der ersten Verwendung zu deklarieren. Da JavaScript jedoch keinen Blockbereich hat, ist es sinnvoller, alle Variablen einer Funktion oben in der Funktion zu deklarieren empfohlen, eine einzelne var-Anweisung pro Funktion zu verwenden. " - http://www.jslint.com/lint.html#scope

Wade Harrell
quelle
6

Ich denke, es ist eine Frage der persönlichen Präferenz. Ich mache es lieber so:

   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
quelle
6

Ein weiterer Grund, die Single-Statement-Version (Single- Var ) zu vermeiden, ist das Debuggen. Wenn in einer der Zuweisungszeilen eine Ausnahme ausgelöst wird, zeigt die Stapelverfolgung nur die eine Zeile an.

Wenn Sie 10 Variablen mit der Kommasyntax definiert haben, können Sie nicht direkt wissen, welche der Schuldige war.

Die Version mit einzelnen Anweisungen leidet nicht unter dieser Mehrdeutigkeit.

Shawn
quelle
2

Das Konzept "Kohäsion über Kopplung" kann allgemeiner angewendet werden als nur Objekte / Module / Funktionen. Es kann auch in dieser Situation dienen:

Das zweite vom OP vorgeschlagene Beispiel hat alle Variablen in dieselbe Anweisung eingekoppelt, was es unmöglich macht, eine der Zeilen zu nehmen und an einen anderen Ort zu verschieben, ohne etwas zu beschädigen (hohe Kopplung). Das erste Beispiel, das er gegeben hat, macht die Variablenzuordnungen unabhängig voneinander (niedrige Kopplung).

"Eine geringe Kopplung ist oft ein Zeichen für ein gut strukturiertes Computersystem und ein gutes Design und unterstützt in Kombination mit einer hohen Kohäsion die allgemeinen Ziele einer hohen Lesbarkeit und Wartbarkeit."

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

Wählen Sie also den ersten.

Magne
quelle
1
Ich verstehe nicht, wie dies mit Kopplung oder Zusammenhalt zusammenhängt. Möchtest du das näher erläutern?
Edson Medina
Das zweite vom OP vorgeschlagene Beispiel hat alle Variablen in dieselbe Anweisung eingekoppelt, was es unmöglich macht, eine der Zeilen zu nehmen und an einen anderen Ort zu verschieben, ohne etwas zu beschädigen (hohe Kopplung). Das erste Beispiel, das er gegeben hat, macht die Variablenzuordnungen unabhängig voneinander (niedrige Kopplung).
Magne
Bei der Kopplung geht es um die gegenseitige Abhängigkeit zwischen verschiedenen Modulen / Objekten / Funktionen, NICHT um Codezeilen!
Edson Medina
1
Ursprünglich ging es um Module, ja, aber das Konzept kann allgemeiner angewendet werden, wie selbst Ihre eigene Einbeziehung von Objekten / Funktionen in die Definition zeigt.
Magne
2

Ein alter Beitrag, ich weiß, aber um ein kleines Detail der Perspektive für andere Googler hinzuzufügen:

Das Problem der Wartbarkeit kann mit ein wenig Formatierung wie dieser ziemlich leicht überwunden werden.

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

Ich verwende diese Formatierung ausschließlich aus persönlichen Gründen. Ich überspringe dieses Format natürlich für einzelne Deklarationen oder wo es einfach die Werke zusammenfasst.

Beau
quelle
1

Ich glaube, bevor wir mit ES6 angefangen haben, war der Ansatz mit einer einzelnen Var-Deklaration weder gut noch schlecht (falls Sie Linters haben und 'use strict'. Es war wirklich eine Geschmackspräferenz. Aber jetzt haben sich die Dinge für mich geändert. Es gibt meine Gedanken zugunsten einer mehrzeiligen Deklaration ::

  1. Jetzt haben wir zwei neue Arten von Variablen und sind varveraltet. Es ist eine gute Praxis, constüberall zu verwenden , bis Sie wirklich brauchen let. Daher enthält Ihr Code häufig Variablendeklarationen mit Zuweisung in der Mitte des Codes, und aufgrund des Blockumfangs verschieben Sie bei kleinen Änderungen häufig Variablen zwischen Blöcken. Ich denke, dass es bequemer ist, dies mit mehrzeiligen Erklärungen zu tun.

  2. Die ES6-Syntax wurde vielfältiger, wir erhielten Destruktoren, Vorlagenzeichenfolgen, Pfeilfunktionen und optionale Zuweisungen. Wenn Sie all diese Funktionen häufig mit einzelnen var-Deklarationen verwenden, beeinträchtigt dies die Lesbarkeit.

Kirill Reznikov
quelle
0

Ich denke, der erste Weg (mehrere Vars) ist der beste, da Sie sonst damit enden können (aus einer Anwendung, die Knockout verwendet), was meiner Meinung nach schwer zu lesen ist:

    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
quelle