He inicializado 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 forma de que pueda configurar todas estas variables con el mismo valor en una línea de código, o el código que tengo actualmente es la mejor manera de hacerlo?
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 se traduce efectivamente a:
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 bastante seguro de que no quería hacer.
Nota: mi ejemplo anterior asume que está ejecutando su código en el navegador, por lo tanto window
. Si tuviera que estar en un entorno diferente, estas variables se adjuntarían a cualquier contexto global para ese entorno (es decir, en Node.js, se adjuntaría a global
que es el contexto global para ese entorno).
Ahora podría declarar primero todas sus variables y luego asignarles el mismo valor y podría evitar el problema.
var moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown;
moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;
Para resumir, 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 sepa sobre la copia por valor frente a la copia por referencia. Siempre 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.
Hay otra opción que no introduce fallos globales al intentar inicializar varias variables con el mismo valor. Si es o no preferible al camino largo es una cuestión de criterio. 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 legible y fácil de mantener, además de ser más rápido.
Él otro forma utiliza Asignación de desestructuración.
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
, let
o const
variables al mismo valor en una sola línea, todas con el mismo alcance esperado.
Referencias:
Coloque la variable en una matriz y use un bucle for para asignar el mismo valor a varias variables.
myArray[moveUP, moveDown, moveLeft];
for(var i = 0; i < myArray.length; i++){
myArray[i] = true;
}
Todos los lectores: vean la segunda respuesta a continuación antes de decidir implementar la respuesta principal en su código. Paz.
– Govind Rai
14 de agosto de 2017 a las 2:39
No intente hacer esto, porque en la memoria solo habrá una variable y las demás serán una copia o referencia para esa, luego, si cambia el valor de una, todas se verán afectadas.
–Lucas Matos
26 de febrero de 2019 a las 19:36
@LucasMatos No para primitivos.
– David Newton
18 de abril de 2020 a las 2:47
sé que no es la respuesta, pero usaría UNA variable “dirección” y en lugar de establecer una variable en falso, uso el triple = para compararlo con verdadero si (moveLeft === verdadero), de esa manera no lo hace necesita establecer el valor inicial en absoluto
– Martijn Scheffer
15 oct 2020 a las 19:15