atribuir várias variáveis ​​ao mesmo valor em Javascript

177

Inicializei várias variáveis ​​no escopo global em um arquivo JavaScript:

var moveUp, moveDown, moveLeft, moveRight;
var mouseDown, touchDown;

Eu preciso definir todas essas variáveis ​​como false, este é o código que tenho atualmente:

moveUp    = false;
moveDown  = false;
moveLeft  = false;
moveRight = false
mouseDown = false;
touchDown = false;

Existe alguma maneira de definir todas essas variáveis ​​com o mesmo valor em uma linha de código ou é o código que atualmente tenho a melhor maneira de fazer isso

SUB-HDR
fonte
8
Todos os leitores: visualize a segunda resposta abaixo antes de decidir implementar a resposta principal em seu código. Paz.
Govind Rai
Não tente fazer isso, porque na memória será apenas uma variável e os outros será uma cópia ou referência para esse, então, se você alterar o valor de um todo será afetado
Lucas Matos
@LucasMatos Não é para primitivos.
Dave Newton

Respostas:

290

Nada impede você de fazer

moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

Veja este exemplo

var a, b, c;
a = b = c = 10;
console.log(a + b + c)

karthikr
fonte
13
Você pode comentar como o comportamento diferirá tipos primitivos e tipos de referência ao atribuir valores da maneira sugerida.
Steven Wexler
26
Sim, se você fizer isso com um objeto, todas as variáveis ​​serão aliases do objeto. O IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xtambém aumentará a b.xpropriedade.
AlexMorley-Finch
27
Problemas de escopo! stackoverflow.com/questions/1758576/…
doublejosh
4
Eu diria que não use essa abordagem se você não estiver abrangendo globalmente todas as variáveis ​​à esquerda da tarefa
citizen conn
2
Como o @doublejosh disse, existem problemas de escopo que você não abordou.
Kstratis # 4/15
90

Nada impede você de fazer o acima, mas aguente!

Existem algumas dicas. A atribuição em Javascript é da direita para a esquerda, então quando você escreve:

var moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

traduz efetivamente para:

var moveUp = (moveDown = (moveLeft = (moveRight = (mouseDown = (touchDown = false)))));

que se traduz efetivamente em:

var moveUp = (window.moveDown = (window.moveLeft = (window.moveRight = (window.mouseDown = (window.touchDown = false)))));

Inadvertidamente, você acabou de criar 5 variáveis ​​globais - algo que tenho certeza de que não queria fazer.

Nota: Meu exemplo acima pressupõe que você esteja executando seu código no navegador window. Se você estivesse em um ambiente diferente, essas variáveis ​​se vinculariam a qualquer que seja o contexto global desse ambiente (por exemplo, no Node.js, ele se anexaria aglobal qual é o contexto global para esse ambiente).

Agora você pode primeiro declarar todas as suas variáveis ​​e depois atribuí-las ao mesmo valor e evitar o problema.

var moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown;
moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

Para encurtar a história, ambas as maneiras funcionariam perfeitamente, mas a primeira maneira poderia introduzir alguns erros perniciosos no seu código. Não cometa o pecado de jogar lixo no espaço de nomes global com variáveis ​​locais, se não for absolutamente necessário.


Nota: Como indicado nos comentários (e esse não é apenas o caso desta pergunta), se o valor copiado em questão não for um valor primitivo, mas um objeto, é melhor conhecer cópia por valor vs cópia por referência. Sempre que atribuir objetos, a referência ao objeto é copiada em vez do objeto real. Todas as variáveis ​​ainda apontam para o mesmo objeto, portanto, qualquer alteração em uma variável será refletida nas outras variáveis ​​e causará uma grande dor de cabeça se sua intenção for copiar os valores do objeto e não a referência.

Govind Rai
fonte
2
e se fizermos o mesmo com let?
P-RAD
Além de ter moveUpum escopo de bloco, não faria diferença. 5 variáveis ​​globais ainda seriam declaradas.
Govind Rai
1
@GovindRai var a, b, c; a = b = c = 10;é muito diferente de var a = b = c = 10;. Portanto, a resposta aceita está correta. Você está solucionando um problema não relacionado à resposta aceita.
Elis Byberi
1
@ElisByberi Obrigado pelo seu comentário. Você não está errado. O objetivo da minha resposta foi abordar a primeira frase da resposta aceita. Forneci mais clareza na minha resposta em relação a isso.
Govind Rai
1
@ P-RAD Apenas a primeira variável declarada usando let existirá no escopo incluído.
Uday Hiwarale
9

Há outra opção que não introduz dicas globais ao tentar inicializar várias variáveis ​​para o mesmo valor. Se é preferível ou não ao longo caminho, é uma decisão judicial. Provavelmente será mais lento e poderá ou não ser mais legível. No seu caso específico, acho que o longo caminho provavelmente é mais legível e sustentável, além de ser mais rápido.

A outra maneira utiliza a atribuição de Reestruturação .

let [moveUp, moveDown,
     moveLeft, moveRight,
     mouseDown, touchDown] = Array(6).fill(false);

console.log(JSON.stringify({
    moveUp, moveDown,
    moveLeft, moveRight,
    mouseDown, touchDown
}, null, '  '));

// NOTE: If you want to do this with objects, you would be safer doing this
let [obj1, obj2, obj3] = Array(3).fill(null).map(() => ({}));
console.log(JSON.stringify({
    obj1, obj2, obj3
}, null, '  '));
// So that each array element is a unique object

// Or another cool trick would be to use an infinite generator
let [a, b, c, d] = (function*() { while (true) yield {x: 0, y: 0} })();
console.log(JSON.stringify({
    a, b, c, d
}, null, '  '));

// Or generic fixed generator function
function* nTimes(n, f) {
    for(let i = 0; i < n; i++) {
        yield f();
    }
}
let [p1, p2, p3] = [...nTimes(3, () => ({ x: 0, y: 0 }))];
console.log(JSON.stringify({
    p1, p2, p3
}, null, '  '));

Isso permite que você inicialize um conjunto de var,let ouconst variáveis ​​com o mesmo valor em uma única linha, todas com o mesmo escopo esperado.

Referências:

Doug Coburn
fonte
1
Cuidado, no entanto. Se atribuir objetos, funções ou matrizes a várias variáveis ​​usando esse método, cada variável será um alias para o sameobjeto. Modificações em um afetarão os outros ...
Doug Coburn
-6

Coloque a variável em uma matriz e use um loop for para atribuir o mesmo valor a várias variáveis.

  myArray[moveUP, moveDown, moveLeft];

    for(var i = 0; i < myArray.length; i++){

        myArray[i] = true;

    }
Tohamas Brewster
fonte
3
Isso está muito errado. A primeira declaração não faz sentido sintático e o loop for está apenas atribuindo valores aos índices myArray.
undefinederror