asignar múltiples variables al mismo valor en Javascript

177

Inicialicé varias variables en el ámbito global en un archivo JavaScript:

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

Necesito establecer todas estas variables en falso, este es el código que tengo actualmente:

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

¿Hay alguna manera de que pueda establecer todas estas variables en el mismo valor en una línea de código, o es el código que tengo actualmente la mejor manera de hacer esto?

SUB-HDR
fuente
8
Todos los lectores: vea la segunda respuesta a continuación antes de decidir implementar la respuesta superior en su código. Paz.
Govind Rai
No intente hacer esto, porque en la memoria solo habrá una variable y las otras serán una copia o referencia para esa, entonces si cambia el valor de uno, todo se verá afectado
Lucas Matos,
@LucasMatos No para primitivos.
Dave Newton

Respuestas:

290

Nada te impide hacer

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

Mira este ejemplo

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

karthikr
fuente
13
Es posible que desee comentar cómo el comportamiento diferirá los tipos primitivos y los tipos de referencia al asignar valores de la manera que sugiere.
Steven Wexler
26
Sí, si se hace esto con un objeto, todas las variables serán alias del objeto. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xtambién incrementará la b.xpropiedad.
AlexMorley-Finch
27
Problemas de alcance! stackoverflow.com/questions/1758576/…
doublejosh
44
Yo diría que no utilice este método si no está a nivel mundial determinación del alcance todas las variables a la izquierda de la asignación del
ciudadano conn
2
Como dijo @doublejosh, hay problemas de alcance que no resolvió.
kstratis
90

Nada te impide hacer lo anterior, ¡pero espera!

Hay algunas trampas. La asignación en Javascript es de derecha a izquierda, así que cuando escribes:

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

se traduce efectivamente a:

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

que efectivamente se traduce en:

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

Sin darse cuenta, acaba de crear 5 variables globales, algo que estoy seguro de que no quería hacer.

Nota: Mi ejemplo anterior supone que está ejecutando su código en el navegador, por lo tanto window. Si estuviera en un entorno diferente, estas variables se unirían a cualquier contexto global para ese entorno (es decir, en Node.js, se vincularía a globalcuál es el contexto global para ese entorno).

Ahora primero puede declarar todas sus variables y luego asignarlas al mismo valor y puede evitar el problema.

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

En pocas palabras, ambas formas funcionarían bien, pero la primera podría potencialmente introducir algunos errores perniciosos en su código. No cometa el pecado de ensuciar el espacio de nombres global con variables locales si no es absolutamente necesario.


Nota al margen: Como se señaló en los comentarios (y esto no es solo en el caso de esta pregunta), si el valor copiado en cuestión no era un valor primitivo sino un objeto, es mejor que conozca copia por valor versus copia por referencia. Cada vez que se asignan objetos, la referencia al objeto se copia en lugar del objeto real. Todas las variables seguirán apuntando al mismo objeto, por lo que cualquier cambio en una variable se reflejará en las otras variables y le causará un gran dolor de cabeza si su intención era copiar los valores del objeto y no la referencia.

Govind Rai
fuente
2
¿Qué pasa si hacemos lo mismo con let?
P-RAD el
Además de moveUptener un alcance de bloque, no habría diferencia. Todavía se declararían 5 variables globales.
Govind Rai
1
@GovindRai var a, b, c; a = b = c = 10;es muy diferente de var a = b = c = 10;. Entonces, la respuesta aceptada es correcta. Está abordando un problema no relacionado con la respuesta aceptada.
Elis Byberi
1
@ElisByberi Gracias por tu comentario. Tu no estas equivocado. El objetivo de mi respuesta era abordar la primera oración de la respuesta aceptada. He proporcionado más claridad en mi respuesta con respecto a eso.
Govind Rai
1
@ P-RAD Solo la primera variable declarada usando let existirá en el ámbito de inclusión.
Uday Hiwarale
9

Hay otra opción que no introduce problemas globales al intentar inicializar múltiples variables al mismo valor. Si es preferible o no al largo camino es una decisión judicial. Probablemente será más lento y puede o no ser más legible. En su caso específico, creo que el camino largo es probablemente más fácil de leer y mantener, además de ser más rápido.

La otra forma utiliza la asignación de Destructuring .

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, '  '));

Esto le permite inicializar un conjunto de var, leto constvariables al mismo valor en una sola línea, todas con el mismo alcance esperado.

Referencias

Doug Coburn
fuente
1
Cuidado, sin embargo. Si asigna objetos, funciones o matrices a múltiples variables utilizando este método, cada variable será un alias para el sameobjeto. Las modificaciones a una afectarán a las demás ...
Doug Coburn
-6

Coloque la variable en una matriz y use un bucle for para asignar el mismo valor a múltiples variables.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }
Tohamas Brewster
fuente
3
Esto está muy mal. La primera declaración no tiene sentido sintáctico y el ciclo for solo asigna valores a los índices myArray.
undefinederror