menetapkan beberapa variabel ke nilai yang sama dalam Javascript

177

Saya telah menginisialisasi beberapa variabel dalam lingkup global dalam file JavaScript:

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

Saya perlu mengatur semua variabel ini menjadi false, ini adalah kode yang saya miliki saat ini:

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

Apakah ada cara saya dapat mengatur semua variabel ini ke nilai yang sama dalam satu baris kode, atau apakah kode saya saat ini memiliki cara terbaik untuk melakukan ini

SUB-HDR
sumber
8
Semua pembaca: silakan lihat jawaban kedua di bawah ini sebelum Anda memutuskan untuk menerapkan jawaban teratas ke dalam kode Anda. Perdamaian.
Govind Rai
Jangan coba-coba melakukan ini, karena di memori hanya ada satu variabel dan yang lain akan menjadi salinan atau referensi untuk yang itu, maka jika Anda mengubah nilai dari satu semua akan terkena dampak
Lucas Matos
@LucasMatos Bukan untuk orang primitif.
Dave Newton

Jawaban:

290

Tidak ada yang menghentikan Anda dari melakukan

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

Lihat contoh ini

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

karthikr
sumber
13
Anda mungkin ingin berkomentar bagaimana perilaku akan berbeda jenis primitif dan tipe referensi ketika menetapkan nilai seperti yang Anda sarankan.
Steven Wexler
26
Ya, jika melakukan ini dengan objek, semua variabel akan menjadi alias dari objek. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xjuga akan menambah b.xproperti.
AlexMorley-Finch
27
Masalah pelingkupan! stackoverflow.com/questions/1758576/…
doublejosh
4
Saya akan mengatakan jangan gunakan pendekatan ini jika Anda tidak secara global melakukan pelingkupan semua variabel di sebelah kiri penugasan
warga negara menghubungkan
2
Seperti yang dikatakan @doublejosh, ada masalah pelingkupan yang tidak Anda atasi.
kstratis
90

Tidak ada yang menghentikan Anda untuk melakukan hal di atas, tetapi tunggu sebentar!

Ada beberapa gotcha. Penugasan dalam Javascript adalah dari kanan ke kiri sehingga ketika Anda menulis:

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

secara efektif diterjemahkan menjadi:

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

yang secara efektif diterjemahkan menjadi:

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

Secara tidak sengaja, Anda baru saja membuat 5 variabel global - sesuatu yang saya cukup yakin tidak ingin Anda lakukan.

Catatan: Contoh saya di atas mengasumsikan Anda menjalankan kode Anda di browser, karenanya window. Jika Anda berada di lingkungan yang berbeda, variabel-variabel ini akan melekat pada apa pun konteks global terjadi untuk lingkungan itu (yaitu, di Node.js, itu akan melampirkan globalyang merupakan konteks global untuk lingkungan itu).

Sekarang Anda bisa mendeklarasikan semua variabel Anda dan kemudian menetapkannya ke nilai yang sama dan Anda bisa menghindari masalah.

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

Singkatnya, kedua cara akan bekerja dengan baik, tetapi cara pertama berpotensi memperkenalkan beberapa bug yang merusak dalam kode Anda. Jangan melakukan dosa mengotori namespace global dengan variabel lokal jika tidak benar-benar diperlukan.


Sidenote: Seperti yang ditunjukkan dalam komentar (dan ini bukan hanya dalam kasus pertanyaan ini), jika nilai yang disalin bukanlah nilai primitif melainkan sebuah objek, Anda lebih baik tahu tentang menyalin berdasarkan nilai vs menyalin dengan referensi. Setiap kali menetapkan objek, referensi ke objek disalin bukan objek yang sebenarnya. Semua variabel masih akan menunjuk ke objek yang sama sehingga setiap perubahan dalam satu variabel akan tercermin dalam variabel lain dan akan menyebabkan Anda sakit kepala besar jika niat Anda adalah untuk menyalin nilai objek dan bukan referensi.

Govind Rai
sumber
2
bagaimana jika kita melakukan ini dengan membiarkan?
P-RAD
Selain moveUpmenjadi tertutup, itu tidak ada bedanya. 5 variabel global masih akan dideklarasikan.
Govind Rai
1
@GovindRai var a, b, c; a = b = c = 10;sangat berbeda dari var a = b = c = 10;. Jadi, jawaban yang diterima benar. Anda sedang mengatasi masalah yang tidak terkait dengan jawaban yang diterima.
Elis Byberi
1
@ElisByberi Terima kasih atas komentar Anda. Kamu tidak salah. Tujuan dari jawaban saya adalah untuk menjawab kalimat pertama dalam jawaban yang diterima. Saya telah memberikan kejelasan lebih lanjut dalam jawaban saya sehubungan dengan itu.
Govind Rai
1
@ P-RAD Hanya variabel pertama yang dideklarasikan menggunakan let akan ada di lingkup terlampir.
Uday Hiwarale
9

Ada opsi lain yang tidak memperkenalkan gotcha global ketika mencoba untuk menginisialisasi beberapa variabel ke nilai yang sama. Apakah itu lebih disukai daripada jangka panjang adalah panggilan penilaian. Kemungkinan akan lebih lambat dan mungkin atau mungkin tidak lebih mudah dibaca. Dalam kasus spesifik Anda, saya pikir bahwa jalan panjang mungkin lebih mudah dibaca dan dikelola serta menjadi lebih cepat.

Cara lain menggunakan penugasan Destrukturisasi .

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

Hal ini memungkinkan Anda untuk menginisialisasi satu set var, letatau constvariabel dengan nilai yang sama pada satu baris semua dengan ruang lingkup yang diharapkan sama.

Referensi:

Doug Coburn
sumber
1
Namun waspadalah. Jika menugaskan Objek, fungsi, atau array ke beberapa variabel menggunakan metode ini, setiap variabel akan menjadi alias ke sameobjek. Modifikasi yang satu akan memengaruhi yang lain ...
Doug Coburn
-6

Letakkan varible dalam array dan Gunakan a untuk Loop untuk menetapkan nilai yang sama ke beberapa variabel.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }
Tohamas Brewster
sumber
3
Ini sangat salah. Pernyataan pertama tidak masuk akal secara sintaksis dan for for hanya memberikan nilai pada indeks myArray.
undefinederror