Saya tahu bahwa ES6 belum terstandarisasi, tetapi banyak browser saat ini mendukung const
kata kunci dalam JS.
Secara spesifik, tertulis bahwa:
Nilai konstanta tidak dapat diubah melalui penetapan ulang, dan konstanta tidak dapat dideklarasikan ulang. Karena itu, meskipun mungkin untuk mendeklarasikan sebuah konstanta tanpa memulainya, hal itu akan sia-sia.
dan ketika saya melakukan sesuatu seperti ini:
const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];
Saya melihat bahwa semuanya ok xxx
masih 6
dan yyy
adalah []
.
Tetapi jika saya melakukannya yyy.push(6); yyy.push(1);
, array konstan saya telah diubah. Sekarang ini [6, 1]
dan omong-omong saya masih tidak bisa mengubahnya dengan yyy = 1;
.
Apakah ini bug, atau saya melewatkan sesuatu? Saya mencobanya di chrome dan FF29 terbaru
javascript
ecmascript-6
const
Salvador Dali
sumber
sumber
Jawaban:
Dokumentasi menyatakan:
Saat Anda menambahkan ke larik atau objek yang tidak Anda tetapkan ulang atau deklarasikan ulang konstanta, itu sudah dideklarasikan dan ditetapkan, Anda hanya menambahkan ke "daftar" yang ditunjuk oleh konstanta.
Jadi ini berfungsi dengan baik:
dan ini:
tapi tidak satu pun dari ini:
sumber
Ini terjadi karena konstanta Anda sebenarnya menyimpan referensi ke array. Ketika Anda menggabungkan sesuatu ke dalam array Anda, Anda tidak mengubah nilai konstanta Anda, tetapi array yang ditunjuknya. Hal yang sama akan terjadi jika Anda menetapkan objek ke konstanta dan mencoba mengubah properti apa pun darinya.
Jika Anda ingin membekukan larik atau objek agar tidak dapat dimodifikasi, Anda dapat menggunakan
Object.freeze
metode yang sudah menjadi bagian dari ECMAScript 5.sumber
five
himpunan konstan ke 5 sebenarnya tidak memiliki nilai 5, itu hanya referensi ke bilangan 5. Jadi jika saya melakukannya,five++
saya tidak mengubah konstanta, hanya angka yang ditunjukkannya.five
(variabel yangfive
dulunya adalah label untuk angka 5, sekarang menunjuk ke angka yang berbeda: 6). Dalam contoh di pertanyaan (dan jawaban ini),x
selalu menunjuk ke daftar yang sama; ifx
is const Anda tidak dapat membuatnya menunjuk ke daftar yang berbeda. Satu-satunya perbedaan adalah bahwa daftar yang sama dapat bertambah atau berkurang; ini adalah sesuatu yang hanya mungkin untuk array dan objek dan bukan untuk primitif.Ini adalah perilaku yang konsisten dengan setiap bahasa pemrograman yang dapat saya pikirkan.
Pertimbangkan C - array hanyalah petunjuk yang dimuliakan. Array konstan hanya berarti bahwa nilai penunjuk tidak akan berubah - tetapi pada kenyataannya data yang terkandung di alamat itu bebas.
Dalam javascript, Anda diizinkan untuk memanggil metode objek konstan (tentu saja - jika objek konstan tidak akan melayani banyak tujuan!) Metode ini mungkin memiliki efek samping memodifikasi objek. Karena array dalam javascript adalah objek, perilaku ini juga berlaku untuk mereka.
Anda hanya yakin bahwa konstanta akan selalu menunjuk ke objek yang sama. Properti dari objek itu sendiri bebas berubah.
sumber
Selain itu, catatan penting juga:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
sumber
Saya pikir ini akan memberi Anda kejelasan lebih lanjut tentang masalah ini: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0 .
Pada dasarnya intinya adalah
const
selalu menunjuk ke alamat yang sama dalam memori. Anda dapat mengubah nilai yang disimpan di alamat itu tetapi tidak dapat mengubah alamat yang ditujuconst
juga.Definisi yang
const
Anda sebutkan akan berlaku saatconst
menunjuk ke alamat yang memiliki nilai primitif. Ini karena Anda tidak dapat menetapkan nilai ke iniconst
tanpa mengubah alamatnya (karena begitulah cara kerja menetapkan nilai primitif) dan mengubah alamat aconst
tidak diperbolehkan.Dimana seolah-olah
const
menunjuk ke nilai non-primitif, dimungkinkan untuk mengedit nilai alamat.sumber
Baca artikel ini sambil mencari alasan mengapa saya bisa memperbarui Object bahkan setelah mendefinisikannya sebagai
const
. Jadi intinya di sini adalah bahwa bukan Objek secara langsung tetapi atribut yang dikandungnya yang dapat diperbarui.Misalnya, Objek saya terlihat seperti:
Jawaban di atas dengan benar menunjukkan bahwa itu adalah Object yang const dan bukan atributnya. Karenanya, saya akan dapat memperbarui id atau nama dengan melakukan:
Tapi, saya tidak akan bisa memperbarui Object itu sendiri seperti:
sumber
Karena dalam const Anda dapat mengubah nilai suatu objek, sehingga objek tersebut tidak benar-benar menyimpan data tugas, tetapi justru menunjuk ke sana. jadi ada perbedaan antara primitif dan objek di Javascript.
sumber