назначить несколько переменных для одного и того же значения в Javascript

177

Я инициализировал несколько переменных в глобальной области видимости в файле JavaScript:

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

Мне нужно установить все эти переменные в false, вот код, который у меня есть:

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

Есть ли способ, которым я могу установить все эти переменные на одно и то же значение в одной строке кода, или код, который у меня в настоящее время есть лучший способ сделать это

SUB-HDR
источник
8
Все читатели: просмотрите второй ответ ниже, прежде чем вы решите внедрить верхний ответ в свой код. Мир.
Говинд Рай
Не пытайтесь сделать это, потому что в памяти будет только одна переменная, а остальные будут копией или ссылкой на
Лукас Матос
@LucasMatos Не для примитивов.
Дейв Ньютон

Ответы:

290

Ничто не мешает вам делать

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

Проверьте этот пример

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

karthikr
источник
13
Вы можете прокомментировать, как поведение будет отличаться от примитивных типов и ссылочных типов при назначении значений так, как вы предлагаете.
Стивен Векслер
26
Да, если делать это с объектом, все переменные будут псевдонимами объекта. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xтакже будет увеличивать b.xсвойство.
AlexMorley-Finch
27
Проблемы с определением объема! stackoverflow.com/questions/1758576/…
doublejosh
4
Я бы сказал, что не используйте этот подход, если вы не определяете глобально все переменные слева от назначения
гражданин 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;

Короче говоря, оба способа будут работать просто отлично, но первый способ может потенциально привести к появлению некоторых вредоносных ошибок в вашем коде. Не совершайте грех засорения глобального пространства имен локальными переменными, если это не является абсолютно необходимым.


Примечание. Как указано в комментариях (и это касается не только этого вопроса), если рассматриваемое копируемое значение было не примитивным, а объектом, вам лучше знать о копировании по значению, а не о копировании по ссылке. При каждом назначении объектов ссылка на объект копируется вместо фактического объекта. Все переменные по-прежнему будут указывать на один и тот же объект, поэтому любое изменение одной переменной будет отражено в других переменных и вызовет у вас сильную головную боль, если вы намереваетесь скопировать значения объекта, а не ссылку.

Говинд Рай
источник
2
что если мы сделаем то же самое с let?
P-RAD
Помимо того, что он moveUpстал ограниченным, это не имело бы значения. 5 глобальных переменных все равно будут объявлены.
Говинд Рай
1
@GovindRai var a, b, c; a = b = c = 10;очень отличается от var a = b = c = 10;. Итак, принятый ответ правильный. Вы решаете проблему, не связанную с принятым ответом.
Элис Бибери
1
@ElisByberi Спасибо за ваш комментарий. Вы не ошиблись. Цель моего ответа состояла в том, чтобы обратиться к первому предложению в принятом ответе. Я дал дополнительную ясность в своем ответе по этому поводу.
Говинд Рай
1
@ P-RAD Только первая переменная, объявленная с использованием let, будет существовать во внешней области видимости.
Uday Hiwarale
10

Есть еще одна опция, которая не вводит глобальные ошибки при попытке инициализировать несколько переменных одним и тем же значением. Является ли это предпочтительным для длинного пути, является решением суда. Это, вероятно, будет медленнее и может быть, а может и не быть более читабельным. В вашем конкретном случае, я думаю, что длинный путь, вероятно, более читабелен и удобен в обслуживании, а также быстрее.

Другой способ использует назначение деструктурирующего .

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, letилиconst переменных к тому же значению на одной линии все с той же ожидаемой областью.

Ссылки:

Дуг Коберн
источник
1
Осторожно, однако. При назначении объектов, функций или массивов нескольким переменным с использованием этого метода каждая переменная будет псевдонимом sameобъекта. Модификации одного коснутся других ...
Дуг Кобурн
0

Перечисленные вами исходные переменные могут быть объявлены и присвоены одному и тому же значению в короткой строке кода с использованием назначения деструктурирования. Ключевые слова let, constи varвсе могут быть использованы для этого типа назначения.

let [moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown] = Array(6).fill(false);
user2887719
источник
-6

Поместите переменную в массив и используйте цикл for, чтобы присвоить одно и то же значение нескольким переменным.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }
Томас Брюстер
источник
3
Это очень неправильно. Первое утверждение не имеет синтаксического смысла, а цикл for просто присваивает значения индексам myArray.
undefinederror