assegnare più variabili allo stesso valore in Javascript


177

Ho inizializzato diverse variabili nell'ambito globale in un file JavaScript:

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

Devo impostare tutte queste variabili su false, questo è il codice che ho attualmente:

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

C'è un modo in cui posso impostare tutte queste variabili sullo stesso valore in una riga di codice o è il codice che attualmente ho il modo migliore per farlo


8
Tutti i lettori: si prega di visualizzare la seconda risposta di seguito prima di decidere di implementare la risposta principale nel proprio codice. Pace.
Govind Rai,

Non provare a farlo, perché in memoria sarà solo una variabile e le altre saranno una copia o un riferimento per quella, quindi se cambi il valore da uno tutto verrà influenzato
Lucas Matos,

@LucasMatos Non per primitivi.
Dave Newton,

Risposte:


290

Niente ti impedisce di fare

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

Guarda questo esempio

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


13
Potresti voler commentare in che modo il comportamento differirà tra tipi primitivi e tipi di riferimento quando assegni i valori nel modo che suggerisci.
Steven Wexler,

26
Sì, se lo fai con un oggetto, tutte le variabili saranno alias dell'oggetto. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xaumenterà anche la b.xproprietà.
AlexMorley-Finch,


4
Direi di non usare questo approccio se non si stanno valutando globalmente tutte le variabili a sinistra del compito
conn conn

2
Come ha detto @doublejosh, ci sono problemi di scoping che non hai affrontato.
kstratis,

90

Nulla ti impedisce di fare quanto sopra, ma reggiti!

Ci sono dei gotchas. L'assegnazione in Javascript è da destra a sinistra, quindi quando scrivi:

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

si traduce efficacemente in:

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

che si traduce efficacemente in:

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

Inavvertitamente, hai appena creato 5 variabili globali - qualcosa che sono abbastanza sicuro che non volevi fare.

Nota: il mio esempio sopra presuppone che tu stia eseguendo il tuo codice nel browser, quindi window. Se dovessi trovarti in un ambiente diverso, queste variabili si legherebbero a qualunque sia il contesto globale per quell'ambiente (cioè, in Node.js, si collegherebbe a globalquale sia il contesto globale per quell'ambiente).

Ora potresti prima dichiarare tutte le tue variabili e poi assegnarle allo stesso valore e potresti evitare il problema.

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

Per farla breve, entrambi i modi funzionerebbero bene, ma il primo modo potrebbe potenzialmente introdurre alcuni bug dannosi nel tuo codice. Non commettere il peccato di sporcare lo spazio dei nomi globale con variabili locali se non assolutamente necessario.


Sidenote: Come sottolineato nei commenti (e questo non è solo nel caso di questa domanda), se il valore copiato in questione non era un valore primitivo ma invece un oggetto, è meglio conoscere copia per valore vs copia per riferimento. Ogni volta che si assegnano oggetti, il riferimento all'oggetto viene copiato anziché l'oggetto reale. Tutte le variabili rimarranno comunque puntate sullo stesso oggetto, quindi qualsiasi cambiamento in una variabile si rifletterà nelle altre variabili e causerà un grosso mal di testa se si intendesse copiare i valori dell'oggetto e non il riferimento.


2
cosa succede se facciamo lo stesso con let?
P-RAD,

Oltre a moveUpdiventare a blocchi, non farebbe alcuna differenza. 5 variabili globali sarebbero comunque dichiarate.
Govind Rai,

1
@GovindRai var a, b, c; a = b = c = 10;è molto diverso da var a = b = c = 10;. Quindi, la risposta accettata è corretta. Stai affrontando un problema non correlato alla risposta accettata.
Elis Byberi

1
@ElisByberi Grazie per il tuo commento. Tu non hai torto. L'obiettivo della mia risposta era indirizzare la prima frase nella risposta accettata. Ho fornito ulteriore chiarezza nella mia risposta al riguardo.
Govind Rai,

1
@ P-RAD Solo la prima variabile dichiarata usando let sarà presente nell'ambito incluso.
Uday Hiwarale,

10

C'è un'altra opzione che non introduce i gotcha globali quando si tenta di inizializzare più variabili allo stesso valore. Se è preferibile o meno la lunga strada è una chiamata di giudizio. Sarà probabilmente più lento e potrebbe o meno essere più leggibile. Nel tuo caso specifico, penso che la lunga strada sia probabilmente più leggibile e mantenibile oltre ad essere più veloce.

L' altro modo utilizza l' incarico di destrutturazione .

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

Ciò consente di inizializzare una serie di var, letoconst variabili allo stesso valore su una singola riga, tutte con lo stesso ambito previsto.

Riferimenti:


1
Attenzione, tuttavia. Se si assegnano oggetti, funzioni o matrici a più variabili usando questo metodo, ogni variabile sarà un alias per l' sameoggetto. Le modifiche a una influenzeranno le altre ...
Doug Coburn,

0

Le variabili originali che hai elencato possono essere dichiarate e assegnate allo stesso valore in una breve riga di codice usando l'assegnazione destrutturante. Le parole chiave let, conste varpossono essere utilizzati per questo tipo di compito.

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

-6

Metti la variabile in un array e usa a for Loop per assegnare lo stesso valore a più variabili.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }

3
Questo è molto sbagliato. La prima affermazione non ha senso sintattico e il ciclo for sta semplicemente assegnando valori agli indici myArray.
undefinederror
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.