призначити декілька змінних одному і тому ж значенню в JavaScript


177

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

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

Мені потрібно встановити всі ці змінні значення false, це код, який у мене зараз є:

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

Чи є спосіб, що я можу встановити всі ці змінні однакове значення в одному рядку коду, або це код, який у мене зараз є найкращим способом зробити це


8
Усі читачі. Будь ласка, перегляньте другу відповідь нижче, перш ніж ви вирішили застосувати головну відповідь у свій код. Мир.
Говінд Рай

Не намагайтеся цього робити, оскільки в пам'яті буде лише одна змінна, а інші будуть копією або посиланням на неї, то, якщо ви зміните значення з одного, все вплине
Лукас Матос,

@LucasMatos Не для примітивів.
Дейв Ньютон

Відповіді:


290

Ніщо не заважає тобі робити

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

Перевірте цей приклад

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


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
Я б сказав, що не використовуйте цей підхід, якщо ви глобально не оцінюєте всі змінні зліва від завдання
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;

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


Sidenote: Як зазначалося в коментарях (і це не лише у випадку з цим питанням), якщо скопійоване значення, про яке йдеться, було не примітивним значенням, а натомість об'єктом, ви краще знаєте копію за значенням проти копіювання за посиланням. Щоразу при призначенні об'єктів посилання на об'єкт копіюється замість фактичного об'єкта. Усі змінні все одно вказуватимуть на один і той же об’єкт, тому будь-яка зміна однієї змінної відображатиметься в інших змінних і спричинятиме вам головний біль, якщо ваш намір полягав у копіюванні об'єктних значень, а не посилань.


2
що, якщо ми зробимо це те саме з нехай?
P-RAD

Окрім того, що moveUpстане блоком, це не має значення. 5 глобальних змінних все ще буде оголошено.
Говінд Рай

1
@GovindRai var a, b, c; a = b = c = 10;дуже відрізняється від var a = b = c = 10;. Отже, прийнята відповідь правильна. Ви вирішуєте проблему, не пов’язану з прийнятою відповіддю.
Elis Byberi

1
@ElisByberi Дякуємо за ваш коментар. Ви не помиляєтесь. Метою моєї відповіді було звернутися до першого речення у прийнятій відповіді. Я надав додаткової ясності у своїй відповіді щодо цього.
Говінд Рай

1
@ P-RAD У першій змінній області існує лише перша змінна, оголошена за допомогою let.
Uday Hiwarale

9

Існує ще один варіант, який не вводить глобальних gotchas при спробі ініціалізації декількох змінних до одного значення. Незалежно від того, чи є кращим довгий шлях, це виклик рішення. Це, швидше за все, буде повільніше, а може бути і не читабельніше. У вашому конкретному випадку я вважаю, що довгий шлях, ймовірно, читабельніший та досконаліший, а також швидший.

Інший спосіб використовує призначення деструктурірующего .

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об'єкта. Зміни одних вплинуть на інші ...
Дуг Коберн

-6

Помістіть змінну в масив та використовуйте для for Loop, щоб призначити одне і те ж значення декільком змінним.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }

3
Це дуже неправильно. Перше твердження не має синтаксичного сенсу, а цикл for - це просто присвоєння значень індексам myArray.
undefinederror
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.