JavaScriptで同じ値に複数の変数を割り当てる


177

JavaScriptファイルのグローバルスコープでいくつかの変数を初期化しました。

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

これらの変数をすべてfalseに設定する必要があります。これは、現在持っているコードです。

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

これらの変数をすべて1行のコードで同じ値に設定できる方法はありますか、または現在これを行うための最良の方法があるコードです。


8
すべての読者:トップの回答をコードに実装する前に、下の2番目の回答をご覧ください。平和。
Govind Rai

メモリ内では1つの変数のみであり、他の変数はその変数のコピーまたは参照になるため、これを実行しないでください。値を1から変更すると、すべてに影響します
Lucas Matos

@LucasMatosプリミティブ用ではありません。
デイブニュートン

回答:


290

何もあなたをやめることを妨げない

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

この例を確認してください

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


13
提案する方法で値を割り当てるときに、動作がプリミティブ型と参照型とどのように異なるかをコメントすることができます。
Steven Wexler 2013年

26
ええ、オブジェクトでこれを行うと、すべての変数はオブジェクトのエイリアスになります。IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xb.xプロパティをインクリメントします。
AlexMorley-Finch 2014

27
スコーピングの問題!stackoverflow.com/questions/1758576/...
doublejosh

4
割り当ての左側にあるすべての変数をグローバルにスコープしていない場合は、このアプローチを使用しないでください
citizen conn

2
@doublejoshが言ったように、あなたが対処しなかったスコープの問題があります。
kstratis

90

上記のことを妨げるものは何もありませんが、頑張ってください!

いくつかの落とし穴があります。JavaScriptでの割り当ては右から左なので、次のように記述します。

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

効果的に次のように変換されます。

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

これは効果的に次のように変換されます。

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

誤って、5つのグローバル変数を作成しただけです。これは、実行したくないと確信しています。

注:私の上記の例では、あなたがそれ故に、ブラウザでコードを実行していると仮定しwindow。別の環境にいる場合、これらの変数は、その環境のグローバルコンテキストが何であってもアタッチします(つまり、Node.jsでは、globalどちらがその環境のグローバルコンテキストにアタッチするか)。

これで、最初にすべての変数を宣言してから、それらを同じ値に割り当てることができ、問題を回避できます。

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

簡単に言えば、どちらの方法でも問題なく機能しますが、最初の方法では、コードに悪質なバグが発生する可能性があります。絶対に必要でなければ、ローカル変数でグローバル名前空間を散らかす罪を犯さないでください。


補足:コメントで指摘されているように(これはこの質問の場合だけではありません)、問題のコピーされた値がプリミティブ値ではなくオブジェクトである場合、値によるコピーと参照によるコピーについてよく理解します。オブジェクトを割り当てると、実際のオブジェクトではなく、オブジェクトへの参照がコピーされます。すべての変数は引き続き同じオブジェクトを指すため、1つの変数の変更は他の変数に反映され、参照ではなくオブジェクトの値をコピーすることが意図されていた場合、大きな問題が発生します。


2
letを使って同じことをしたらどうなるでしょう?
P-RAD 2018

moveUpブロックスコープになる以外は、何の違いもありません。5つのグローバル変数が宣言されます。
Govind Rai

1
@GovindRaiはとvar a, b, c; a = b = c = 10;は大きく異なりvar a = b = c = 10;ます。だから、受け入れられた答えは正しいです。受け入れられた回答に関連しない問題に対処しています。
Elis Byberi

1
@ElisByberiコメントありがとうございます。あなたは間違っていません。私の回答の目的は、受け入れられた回答の最初の文に取り組むことでした。それに関しては、私の回答をさらに明確にしました。
Govind Rai

1
@ P-RAD letを使用して宣言された最初の変数のみが、外側のスコープに存在します。
Uday Hiwarale

9

複数の変数を同じ値に初期化しようとするときに、グローバルな問題を導入しない別のオプションがあります。長い道のりのほうが望ましいかどうかは、判断の呼びかけです。遅くなる可能性が高く、読みやすくなる場合とそうでない場合があります。あなたの特定のケースでは、長い道のりはおそらくより読みやすく保守しやすく、高速であると思います。

もう1つの方法では、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, '  '));

これにより、、、または変数のセットをvar、期待されるスコープがすべて同じ1行で同じ値に初期化できます。letconst

参照:


1
ただし、注意してください。このメソッドを使用してオブジェクト、関数、または配列を複数の変数に割り当てる場合、各変数はsameオブジェクトのエイリアスになります。1つの変更は他のユーザーに影響を与えます...
Doug Coburn

-6

変数を配列に入れ、forループを使用して同じ値を複数の変数に割り当てます。

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }

3
これは非常に間違っています。最初のステートメントは構文的に意味がなく、forループはmyArrayインデックスに値を割り当てるだけです。
undefinederror
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.