Declarando várias variáveis ​​em JavaScript

334

Em JavaScript, é possível declarar várias variáveis ​​como esta:

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

...ou assim:

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

Um método é melhor / mais rápido que o outro?

Steve Harrison
fonte
6
Quanto mais rápido , usando esse jsperf, não pude ver um ganho consistente de velocidade usando um método ou outro.
Majid Fouladpour

Respostas:

345

A primeira maneira é mais fácil de manter. Cada declaração é uma única declaração em uma única linha, para que você possa adicionar, remover e reordenar facilmente as declarações.

Com a segunda maneira, é irritante remover a primeira ou a última declaração porque elas contêm a varpalavra - chave e o ponto-e-vírgula. E toda vez que você adiciona uma nova declaração, é necessário alterar o ponto e vírgula na linha antiga para uma vírgula.

Jeremy Ruten
fonte
67
Se você estiver escrevendo um código que espera compactar ou compactar posteriormente, a segunda maneira permite que os compressores (como o YUI Compressor) ofereçam uma versão mais minificada. Se o tamanho é uma consideração, sugiro seguir o maior número possível de sugestões da JSLint.
Lane
36
jslint afirma que o segundo caminho é mais justo, mas eu discordo.
precisa saber é o seguinte
29
A segunda maneira é uma micro-otimização. Todas as declarações var são processadas de uma só vez, em vez de uma de cada vez. Isso não importa muito em navegadores modernos / computadores modernos.
Webnesto
18
@ 0xc0de: Eu gostaria de ver a prova de declarar todas as variáveis ​​em uma declaração como "eficiente". Se você está medindo apenas a eficiência como uma questão de poucos bytes salvos, talvez seja. Mas se você levar em conta a legibilidade e a capacidade de manutenção, acho que você descobrirá que a otimização prematura geralmente é o caminho errado, principalmente porque os navegadores modernos coletam e inicializam todas as variáveis ​​do escopo em um passo de pré-execução. Pessoalmente, acho que ter todas as variáveis ​​declaradas em uma única linha ou instrução para tornar o entendimento rápido do código mais difícil e mais propenso a erros.
ogradyjd
9
No que diz respeito à eficiência, o uglifyjs e o compilador de fechamento do Google comprimem automaticamente as instruções var sequenciais em uma, tornando esse ponto discutível (até onde eu sei que a YUI não fará isso, no entanto, não testei extensivamente).
bhuber
215

Além da capacidade de manutenção, a primeira maneira elimina a possibilidade de criação de variáveis ​​globais de acidentes:

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

Enquanto a segunda maneira é menos tolerante:

(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
fonte
4
Bom ponto. Se eles são curtos, em seguida, escrever em uma única linha irá evitar este problema: var variable1 = "Hello World!", variable2 = "Testing...", variable3 = 42;. A falta ,irá falhar, mas concordo que é arriscado
Aram Kocharyan
14
Se você estiver usando o modo estrito, não poderá criar globais como este.
Danyal Aytekin 24/10/12
1
Sou fã de declarar várias variáveis ​​em uma única linha porque acho que parece mais limpo. Dito isto, declarar acidentalmente variáveis ​​globais é um perigo real. Enquanto procurava vazamentos de memória, deparei-me com várias instâncias em que acidentalmente declarei várias variáveis ​​globais de uma só vez, porque usei um ponto-e-vírgula em vez de vírgula.
precisa saber é o seguinte
O +1 passa metade do dia e até começa a se perguntar por que há uma diferença indocumentada entre essas duas declarações. Em seguida, leia esta resposta, verifiquei o código com muito cuidado e encontrou o erro. Preciso de um feriado ... #
28713 Giedrius
1
Meu editor de texto me dá um Possible Fatal Errorse eu perder um coma, viva para mim!
33

É comum usar uma vardeclaração por escopo para organização. A maneira como todos os "escopos" seguem um padrão semelhante, tornando o código mais legível. Além disso, o mecanismo "eleva" todos eles ao topo de qualquer maneira. Portanto, manter suas declarações juntas imita o que realmente acontecerá mais de perto.

spencer.sm
fonte
6
Você pode manter as declarações juntas sem fazê-las compartilhar a mesma declaração 'var'. Compreendo e aceito as explicações dadas em jslint (seu link), mas não compartilho a conclusão. Como dito acima, é mais uma questão de estilo do que qualquer outra coisa. No mundo Java (entre outros), o inverso (uma declaração por linha) é recomendado para facilitar a leitura.
PhiLho
Mais legível? A única razão pela qual as pessoas as colocam em uma linha é a razão específica de JS que você mencionou: JS move todas as declarações para o topo. Se não fizesse isso, todos estaríamos declarando nossos vars mais próximos do ponto em que são usados.
Danyal Aytekin 24/10/12
@ vol7ron não é esse o caso e é um grande mal-entendido da vardeclaração. O oposto é verdadeiro. consulte a documentação e este exemplo
jackweirdy
@jackweirdy você está correto e foi esse o caso, má implementação ou bug em navegadores antigos. Eu já excluí meu comentário.
precisa saber é o seguinte
29

É muito mais legível ao fazê-lo desta maneira:

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

Mas ocupa menos espaço e linhas de código desta maneira:

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

Pode ser ideal para economizar espaço, mas permita que os compressores JavaScript cuidem disso para você.

Jason Stackhouse
fonte
15

Talvez assim

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

Exceto ao alterar a primeira ou a última variável, é fácil manter e ler.

joe nerdan
fonte
6
Normalmente, usando vírgula primeiro, o ponto-e-vírgula entra em uma nova linha para evitar esse problema. var variável1 = "olá mundo" \ n, variável2 = 2 \ n, variável3 = "como você está" \ n, variável4 = 42 \ n; \ n
BrianFreud
2
Essa é a sintaxe Haskell. Eu sinto que a prática de alguma forma, não é recomendado / comum em javascript
shamanSK
14

É apenas uma questão de preferência pessoal. Não há diferença entre essas duas maneiras, exceto alguns bytes salvos com o segundo formulário, se você remover o espaço em branco.

Brian Campbell
fonte
O segundo salva alguns bytes.
Sophie Alpert
Ben Alpert: Como você imagina?
Josh Stodola
Se você remover o espaço em branco, então 'var foo = "olá", bar = "world";' declaração ocupa menos caracteres que 'var foo = "olá"; var bar = "world";' Se você tem um site popular, salvar alguns bytes na JS pode ajudar (você também gostaria de minimizar os nomes de variáveis, etc)
Brian Campbell
Vejo isso os bytes salvos como irrelevantes no momento, devido ao aumento dos minificadores de JavaScript, principalmente o modo simples (chamado) do Google Closer Compiler.
Bryan Campo
1
@webnesto nunca há desempenho da sintaxe quando a semântica da mesma é a mesma. Não se executa código imediatamente, mas primeiro o analisa e faz a análise semântica - é aqui que os dois estilos de declaração são equalizados.
Esailija
14

O ECMAScript6 introduziu uma atribuição de desestruturação que funciona muito bem:

[a, b] = [1, 2] aserá igual 1e bserá igual 2.

Nir Naor
fonte
não responde à pergunta, mas pode ser uma alternativa melhor para as duas abordagens descritas.
Svarog 22/09/16
1
Eu acho que sua abordagem não é realmente viável, caso você tenha longas listas de variáveis. É difícil dizer para qual variável qual valor está relacionado e também você não tem proteção contra erros. É um caso de mesclagem incorreta durante a qual você acidentalmente pode remover um elemento de uma matriz. Exemplo: let [aVar, bVar, cVar, xVar, yVar, zVar] = [10, 20, 30, 40, 50]; Então, pessoalmente, eu não recomendo.
Kirill Reznikov
1
útil se você deseja definir muitas variáveis ​​com os mesmos valores. Usando para redefinir para zero em um loop, por exemplo.
Nick
Sim! era isso que eu estava procurando. Especialmente se você deseja definir um par bidimensional ou valores multidimensionais, mas não matrizes.
Eugene Kardash
11
var variable1 = "Hello World!";
var variable2 = "Testing...";
var variable3 = 42;

é mais legível que:

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

Mas eles fazem a mesma coisa.

Kevin Crowell
fonte
Usa menos "espaço no arquivo"? Eu acho que você tem algumas explicações a fazer.
Josh Stodola
@ JoshStodola parece o mesmo espaço no arquivo para mim. Desde que var<space>, em vez disso ,<space><space><space><space>
WORMSS 18/18/18
@WORMSS a menos que seja var<space>ou var<tab>vs <tab>. Ainda em grande parte discutível.
Mpag 17/08
9

Usar a atribuição de reestruturação do ES6 : descompactará valores de matrizes ou propriedades de objetos em variáveis ​​distintas.

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

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

Rohit Jindal
fonte
4
É uma péssima idéia, especialmente se você precisar atribuir cerca de 10 variáveis.
Kirill Reznikov
7

Meu único e essencial uso de vírgula é um loop for:

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

Eu fui aqui para verificar se isso está OK em JavaScript.

Mesmo vendo funcionar, permaneceu uma questão de saber se n é local para a função.

Isso verifica, n é 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");

Por um momento não tive certeza, alternando entre idiomas.

codelion
fonte
7

Embora ambos sejam válidos, o uso do segundo desencoraja desenvolvedores inexperientes de colocar instruções var em todo o lugar e causar problemas de içamento. Se houver apenas um var por função, na parte superior da função, será mais fácil depurar o código como um todo. Isso pode significar que as linhas em que as variáveis ​​são declaradas não são tão explícitas quanto algumas podem desejar.

Eu sinto que a troca vale a pena, se isso significa afastar um desenvolvedor de deixar 'var' em qualquer lugar que eles desejarem.

As pessoas podem reclamar do JSLint, também, mas muito disso é voltado não para corrigir problemas com a linguagem, mas para corrigir os maus hábitos dos codificadores e, portanto, evitar problemas no código que eles escrevem. Portanto:

"Em idiomas com escopo de bloco, geralmente é recomendável que variáveis ​​sejam declaradas no site de primeiro uso. Mas, como o JavaScript não possui escopo de bloco, é mais prudente declarar todas as variáveis ​​de uma função na parte superior da função. recomendado que uma única instrução var seja usada por função ". - http://www.jslint.com/lint.html#scope

Wade Harrell
fonte
6

Eu acho que é uma questão de preferência pessoal. Eu prefiro fazê-lo da seguinte maneira:

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

Outro motivo para evitar a versão de instrução única ( var única ) é a depuração. Se uma exceção for lançada em qualquer uma das linhas de atribuição, o rastreamento de pilha mostrará apenas uma linha.

Se você tivesse 10 variáveis ​​definidas com a sintaxe da vírgula, não terá como saber diretamente qual foi o culpado.

A versão da declaração individual não sofre com essa ambiguidade.

Shawn
fonte
2

O conceito de "Coesão sobre acoplamento" pode ser aplicado de maneira mais geral do que apenas objetos / módulos / funções. Também pode servir nesta situação:

O segundo exemplo sugerido pelo OP acoplou todas as variáveis ​​na mesma instrução, o que torna impossível pegar uma das linhas e movê-la para outro lugar sem interromper o material (acoplamento alto). O primeiro exemplo que ele deu torna as atribuições variáveis ​​independentes uma da outra (baixo acoplamento).

"O baixo acoplamento costuma ser um sinal de um sistema de computador bem estruturado e de um bom design, e quando combinado com alta coesão, suporta os objetivos gerais de alta legibilidade e manutenção".

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

Então escolha o primeiro.

Magne
fonte
1
Não vejo como isso está relacionado ao acoplamento ou coesão. Cuidado ao elaborar?
Edson Medina
O segundo exemplo sugerido pelo OP acoplou todas as variáveis ​​na mesma instrução, o que torna impossível pegar uma das linhas e movê-la para outro lugar sem interromper o material (acoplamento alto). O primeiro exemplo que ele deu torna as atribuições variáveis ​​independentes uma da outra (baixo acoplamento).
Magne
O acoplamento é sobre interdependência entre diferentes módulos / objetos / funções, NÃO linhas de código!
Edson Medina
1
Originalmente, tratava-se de módulos, sim, mas o conceito pode ser aplicado de maneira mais geral, como mostra sua própria inclusão de objetos / funções na definição.
Magne
2

Um post antigo, eu sei, mas para adicionar um pequeno detalhe de perspectiva aos colegas Googlers:

O problema de manutenção pode ser facilmente superado com um pouco de formatação, como tal.

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

Eu uso essa formatação estritamente como uma questão de preferência pessoal. Eu pulo esse formato para declarações únicas, é claro, ou onde ele simplesmente anima as obras.

Beau
fonte
1

Acredito que antes de começarmos a usar o ES6, a abordagem com uma única declaração var não era boa nem ruim (no caso de você ter linters e 'use strict'. Foi realmente uma preferência de gosto. Mas agora as coisas mudaram para mim. Existem meus pensamentos a favor da declaração multilinha :

  1. Agora, temos dois novos tipos de variáveis ​​e nos vartornamos obsoletos. É uma boa prática usar em constqualquer lugar até que você realmente precise let. Frequentemente, seu código conterá declarações de variáveis ​​com atribuição no meio do código e, devido ao escopo do bloco, você frequentemente moverá variáveis ​​entre os blocos em caso de pequenas alterações. Eu acho que é mais conveniente fazer isso com declarações multilinhas.

  2. A sintaxe do ES6 tornou-se mais diversificada, obtivemos destruidores, seqüências de modelos, funções de seta e atribuições opcionais. Quando você usa intensamente todos esses recursos com uma única declaração var, isso prejudica a legibilidade.

Kirill Reznikov
fonte
0

Eu acho que a primeira maneira (vários vars) é a melhor, pois você pode acabar com isso (a partir de um aplicativo que usa o Knockout), que é difícil de ler na minha opinião:

    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
fonte