merusak objek tanpa var


97

Mengapa penghancuran objek membuat kesalahan jika tidak ada varkata kunci di depannya?

{a, b} = {a: 1, b: 2};

melempar SyntaxError: expected expression, got '='

Tiga contoh berikut bekerja tanpa masalah

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

Pertanyaan bonus: Mengapa kita tidak membutuhkan sebuah varfor array destructuring?

Saya mengalami masalah saat melakukan sesuatu seperti

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Jawaban:


158

Masalahnya berasal dari {...}operator yang memiliki banyak arti dalam JavaScript.

Saat {muncul di awal Pernyataan , itu akan selalu mewakili blok , yang tidak dapat ditetapkan. Jika nanti muncul di Pernyataan sebagai Ekspresi , maka itu akan mewakili Objek.

Bantuan varmembuat perbedaan ini, karena tidak dapat diikuti oleh Pernyataan , seperti halnya pengelompokan tanda kurung :

( {a, b} = objectReturningFunction() );

Dari dokumen mereka: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

Catatan: Tanda kurung (...) di sekitar pernyataan tugas diperlukan saat menggunakan tugas penghancuran literal objek tanpa deklarasi.

{a, b} = {a: 1, b: 2} bukan sintaks berdiri sendiri yang valid, karena {a, b} di sisi kiri dianggap sebagai blok dan bukan literal objek.

Namun, ({a, b} = {a: 1, b: 2}) valid, seperti var {a, b} = {a: 1, b: 2}

Ekspresi (...) Anda harus diawali dengan titik koma atau mungkin digunakan untuk menjalankan fungsi pada baris sebelumnya.


Jika nanti muncul di Pernyataan sebagai Ekspresi, maka itu akan mewakili Objek. Apakah ini berarti kita tidak pernah dapat memiliki cakupan blok di dalam kurung pengelompokan
sharad_kalya

Tip tanda kurung pengelompokan sangat bagus.
James Smith

Ini adalah sedikit pengetahuan yang sangat tidak jelas yang membuat saya bingung. Ini memungkinkan penghancuran di seluruh ruang lingkup (yah, semacam - Anda masih perlu mendeklarasikan variabel Anda, tentu saja). Tapi itu memecahkan kendala menggunakan rantai Janji sambil perlu menggunakan banyak variabel yang diselesaikan dari satu langkah rantai Janji di langkah lain, tanpa membuat terlalu banyak kekacauan. Terima kasih.
Kevin Teljeur

23

Jika Anda menulis Javascript tanpa titik koma , maka sintaks 'assignment without declaration' harus diawali dengan titik koma agar berfungsi dengan baik.

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

Hanya ingin menyoroti ini karena hal itu menarik perhatian saya, dan semoga dapat menghemat waktu orang lain untuk mencari tahu mengapa itu tidak berfungsi dan / atau menghasilkan hasil yang aneh dengan pemformat kode seperti prettier.

Memang, itu sebenarnya ada di jawaban yang diterima (baris terakhir dari dokumen yang dikutip) tetapi mudah dilewatkan, terutama tanpa melihat contoh!


1
Ya. Alasan orang menggunakan titik koma!
jfriend00

1

Berikut cara lain:

let {} = {a, b} = objectReturningFunction()

Kelebihan:

  • Tidak perlu tanda kurung
  • Tidak perlu titik koma
  • Penugasan tambahan adalah jaminan tanpa operasi (mengingat tidak ada hal aneh yang terjadi)

Kekurangan:

  • Terlihat agak aneh, meski menurut saya tidak lebih aneh dari !(){...}() IIFE .
  • Mungkin membingungkan mengapa itu ada di sana. Dijamin akan membuat orang-orang tidak senang pada pertemuan pertama, jadi saya akan menyarankan agar tidak menggunakannya sebagai satu kali saja.

Rasanya seperti IIFE lebih sebanding dengan ;({ a, b })daripada let {} = { ... }. Trik yang bagus. :)
shuckster

@ proto-n, +1, ide yang sangat cerdas. Bagaimana Anda menemukan ini?
Pacerier
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.