przypisz wiele zmiennych do tej samej wartości w JavaScript

177

Zainicjowałem kilka zmiennych w zakresie globalnym w pliku JavaScript:

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

Muszę ustawić wszystkie te zmienne na false, to jest kod, który obecnie mam:

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

Czy istnieje sposób, w jaki mogę ustawić wszystkie te zmienne na tę samą wartość w jednym wierszu kodu, czy też kod, który obecnie mam najlepszy sposób, aby to zrobić

SUB-HDR
źródło
8
Wszyscy czytelnicy: przeczytaj drugą odpowiedź poniżej, zanim zdecydujesz się zaimplementować pierwszą odpowiedź w swoim kodzie. Pokój.
Govind Rai
Nie próbuj tego robić, ponieważ w pamięci będzie tylko jedna zmienna, a pozostałe będą kopią lub odniesieniem dla tej jednej, to jeśli zmienisz wartość z jednej, wpłynie to na wszystko
Lucas Matos
@LucasMatos Nie dla prymitywów.
Dave Newton

Odpowiedzi:

290

Nic cię nie powstrzymuje

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

Sprawdź ten przykład

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

karthikr
źródło
13
Możesz skomentować, w jaki sposób zachowanie będzie się różniło od typów pierwotnych i typów referencyjnych podczas przypisywania wartości w sposób, który sugerujesz.
Steven Wexler
26
Tak, jeśli robisz to z obiektem, wszystkie zmienne będą aliasami obiektu. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xzwiększy również b.xwłaściwość.
AlexMorley-Finch
27
Problemy z zasięgiem! stackoverflow.com/questions/1758576/…
doublejosh
4
Powiedziałbym, że nie używaj tego podejścia, jeśli nie oceniasz globalnie wszystkich zmiennych po lewej stronie zadania
obywatel conn
2
Jak powiedział @doublejosh, są problemy z zakresem, których nie rozwiązałeś.
kstratis
90

Nic nie powstrzymuje Cię przed zrobieniem powyższego, ale poczekaj!

Jest kilka pułapek. Przypisanie w Javascript jest od prawej do lewej, więc kiedy piszesz:

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

skutecznie przekłada się na:

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

co skutecznie przekłada się na:

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

Nieumyślnie właśnie utworzyłeś 5 zmiennych globalnych - jestem pewien, że nie chciałeś tego robić.

Uwaga: Mój powyższy przykład zakłada, że ​​uruchamiasz swój kod w przeglądarce, stąd window. Gdybyś był w innym środowisku, te zmienne byłyby dołączone do dowolnego kontekstu globalnego dla tego środowiska (tj. W Node.js, byłyby one dołączone do globalkontekstu globalnego tego środowiska).

Teraz możesz najpierw zadeklarować wszystkie swoje zmienne, a następnie przypisać im tę samą wartość, aby uniknąć problemu.

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

Krótko mówiąc, oba sposoby działałyby dobrze, ale pierwszy sposób może potencjalnie wprowadzić do kodu zgubne błędy. Nie popełniaj grzechu zaśmiecania globalnej przestrzeni nazw zmiennymi lokalnymi, jeśli nie jest to absolutnie konieczne.


Uwaga dodatkowa: Jak wskazano w komentarzach (i to nie tylko w przypadku tego pytania), jeśli skopiowana wartość nie była wartością pierwotną, ale obiektem, lepiej wiesz o kopiowaniu według wartości w porównaniu z kopiowaniem przez odniesienie. Przy przypisywaniu obiektów zamiast rzeczywistego obiektu kopiowane jest odniesienie do obiektu. Wszystkie zmienne będą nadal wskazywały na ten sam obiekt, więc każda zmiana jednej zmiennej zostanie odzwierciedlona w innych zmiennych i spowoduje duży ból głowy, jeśli zamierzałeś skopiować wartości obiektu, a nie odniesienie.

Govind Rai
źródło
2
co jeśli zrobimy to samo z let?
P-RAD
Poza moveUptym, że ma zasięg blokowy, nie miałoby to znaczenia. 5 zmiennych globalnych nadal byłoby zadeklarowanych.
Govind Rai,
1
@GovindRai var a, b, c; a = b = c = 10;bardzo różni się od var a = b = c = 10;. Tak więc przyjęta odpowiedź jest prawidłowa. Rozwiązujesz problem niezwiązany z zaakceptowaną odpowiedzią.
Elis Byberi,
1
@ElisByberi Dzięki za komentarz. Nie mylisz się. Celem mojej odpowiedzi było odniesienie się do pierwszego zdania w zaakceptowanej odpowiedzi. W mojej odpowiedzi udzieliłem dalszej jasności w tej sprawie.
Govind Rai
1
@ P-RAD Tylko pierwsza zmienna zadeklarowana przy użyciu let będzie istnieć w otaczającym zakresie.
Uday Hiwarale
9

Istnieje inna opcja, która nie wprowadza globalnych problemów podczas próby zainicjowania wielu zmiennych na tę samą wartość. To, czy jest to lepsze od długiej drogi, czy nie, jest decyzją sądu. Prawdopodobnie będzie wolniejszy i może, ale nie musi, być bardziej czytelny. W twoim konkretnym przypadku myślę, że długa droga jest prawdopodobnie bardziej czytelna i łatwa w utrzymaniu, a także jest szybsza.

Inny sposób wykorzystuje zadanie rozpad .

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

To pozwala zainicjować zestawu var, letlub constzmienne do tej samej wartości w jednym wierszu wszystkie z tego samego zakresu oczekiwanego.

Bibliografia:

Doug Coburn
źródło
1
Uważaj jednak. W przypadku przypisywania obiektów, funkcji lub tablic do wielu zmiennych za pomocą tej metody, każda zmienna będzie aliasem sameobiektu. Modyfikacje jednego wpłyną na inne…
Doug Coburn
-6

Umieść zmienną w tablicy i użyj pętli for, aby przypisać tę samą wartość do wielu zmiennych.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }
Tohamas Brewster
źródło
3
Jest to bardzo błędne. Pierwsza instrukcja nie ma sensu składniowego, a pętla for po prostu przypisuje wartości do indeksów myArray.
nieokreślony błąd