Objek yang bisa berubah
Dalam JavaScript, objek adalah data tipe referensi. Keuntungannya adalah bahwa ketika objek sering dimodifikasi, mereka dimodifikasi berdasarkan objek asli dan tidak perlu diciptakan kembali. Ini dapat secara efektif memanfaatkan memori dan tidak akan menyebabkan pemborosan ruang memori. Fitur objek ini dapat disebut berubah, yang berarti "dapat berubah" dalam bahasa Cina.
Untuk objek yang dapat berubah, fleksibilitas dan perubahannya terkadang dapat menjadi kerugiannya. Semakin fleksibel dan berubah data, semakin sulit untuk mengontrol. Untuk objek dengan struktur yang kompleks, data secara tidak sengaja dimodifikasi secara tidak sengaja. Jika objek digunakan dalam beberapa lingkup, sulit untuk melihat apakah dan kapan data akan berubah.
var obj = {/* Objek dengan struktur kompleks*/}; dosomething (obj); // Setelah garis fungsi di atas selesai, apakah OBJ masih obj asli saat ini?Untuk mengatasi masalah ini, solusi konvensional dapat menyalin objek baru dengan mendalam menyalin objek dan kemudian memodifikasinya pada objek baru. Ini dapat memastikan kemampuan kontrol data, tetapi penyalinan yang sering akan menyebabkan banyak pemborosan ruang memori.
var obj = {/* Objek dengan struktur kompleks*/}; // salin membuat obj2 // baru tetapi operasi salinan akan membuang ruang memori var obj2 = deepclone (obj); dosomething (obj2); // Setelah fungsi di atas selesai, terlepas dari apakah perubahan OBJ2, OBJ pasti akan menjadi OBJ asli awalObjek yang tidak dapat diubah
Untuk menyelesaikan masalah di atas dengan lebih baik, objek yang tidak dapat diubah muncul, yang "tidak berubah" diterjemahkan secara harfiah ke dalam bahasa Mandarin. Setiap kali objek yang tidak dapat diubah dimodifikasi, objek immutable baru dibuat. Operasi pada objek baru tidak akan mempengaruhi data objek asli. Objek khusus ini bukanlah fitur fungsional baru dari JavaScript, tetapi serangkaian solusi yang disediakan oleh industri untuk menyelesaikan masalah ini, dan beberapa perpustakaan open source yang sangat baik telah muncul, yang paling terkenal di antaranya adalah open source immutable.js Lee Byron dari Facebook. Tentu saja, solusi Immutable bukan asli, tetapi berasal dari Clojure dan Scala.
Perbandingan kinerja antara berubah dan tidak berubah
Operasi yang tidak efisien dari objek yang dapat berubah terutama tercermin dalam replikasi dan perbandingan, dan objek yang tidak dapat diubah memecahkan dua titik nyeri yang tidak efisien ini.
Operasi salinan dalam objek yang dapat berubah secara biasa akan menyalin seluruh data. Objek yang tidak dapat diubah tidak akan menyalin seluruh data saat memodifikasi data, tetapi akan mentransfer hubungan orangtua-anak antara simpul yang diubah dan simpul yang tidak berubah ke node baru, mirip dengan struktur daftar yang ditautkan. Dari perspektif "salinan", minimalisasi replikasi tercapai, dan bagian yang tidak berubah dibagi. Mutable adalah "penuh" saat menyalin, sedangkan abadi adalah "inkremental", yang menentukan laju penggunaan memori penggunaan tinggi atau rendah.
Dan berdasarkan fitur bahwa setiap kali objek yang tidak dapat diubah dimodifikasi, objek immutable baru akan dibuat. Ini dapat menyimpan status data yang dimodifikasi ke dalam satu set snapshot, yang juga cukup nyaman.
Mari kita bicara tentang operasi perbandingan. Untuk objek yang dapat berubah, jika Anda ingin membandingkan apakah kedua objek itu sama, Anda harus melintasi setiap simpul objek untuk perbandingan. Untuk objek dengan struktur yang kompleks, efisiensinya jelas tidak jauh lebih tinggi. Untuk objek yang tidak dapat diubah, Immutable.js menyediakan API yang secara langsung menentukan apakah "nilai" dari dua objek yang tidak dapat diubah adalah sama.
var map1 = immutable.map ({a: 1, b: 1, c: 1}); var map2 = immutable.map ({a: 1, b: 1, c: 1}); assert (map1! == map2); // Untuk berbagai contoh yang tidak dapat diubah, alamat referensi menegaskan (immutable.is (MAP1, MAP2)); // Nilai MAP1 dan MAP2 sama, dan nilai -nilai menegaskan (MAP1.Equals (MAP2)); // Fungsi kekambuhan.Dalam aplikasi pengembangan yang sebenarnya, kinerja tidak selalu yang paling kritis dan penting. Untuk proyek JavaScript biasa, kemampuan pengendalian data yang disebabkan oleh karakteristik kekambuhan lebih menguntungkan daripada kinerja. Untuk objek yang dapat berubah, ini cocok untuk digunakan dalam ruang lingkup tertutup, sementara benda yang tidak dapat diubah cocok untuk digunakan ketika data perlu dilewati di beberapa lingkup.
Perbedaan antara berubah -ubah dan tidak berubah
Immutable.js menyediakan berbagai struktur data yang tidak dapat ditentukan: termasuk daftar stack peta stack orderedmap. Catatan orderedset, yang kira -kira sesuai dengan struktur data yang dapat berubah native.
Saya tidak akan menjelaskan penggunaan setiap struktur data di sini, tetapi terutama berbicara tentang perbedaan antara penggunaan objek yang tidak dapat diubah dan objek yang dapat berubah.
Objek asli yang dapat berubah sangat nyaman untuk "membaca" dan "menulis".
var mutableobj = {}; // tulis data mutableobj.foo = 'bar'; // baca data konsol.log (mutableobj.foo);Objek yang tidak dapat diubah perlu "membaca" dan "menulis" data melalui set dan dapatkan.
var immutableObj1 = immutable.map (); // tulis data var immutableObj2 = immutableObj1.set ('foo', 'bar'); // baca data konsol.log (immutableoBj2.get ('foo')); // => 'bar'Untuk mengilustrasikan penggunaan metode yang ditetapkan, contoh di atas membuat objek kosong di awal, dan pada kenyataannya, nilai awal dapat dilewati selama instantiasi.
var immutableObj = immutable.map ({'foo', 'bar'});Untuk data dengan level yang lebih dalam, antarmuka akses yang disediakan oleh Immutable.js sangat nyaman.
var immutableObj1 = immutable.fromjs ({a: {b: 'c'}, d: [1, 2, 3]}); // Baca konsol data yang dalam. // => 'c'console.log (immutableobj1.getin ([' a ',' b '])); // => 2 // Ubah data dalam var immutableObj2 = immutableObj1.setin (['a', 'b'], 'd'); console.log (immutableobj2.getin (['a', 'b'])); // => 'd'Jika ini adalah objek yang dapat berubah native, kesalahan yang tidak ditentukan dapat dilaporkan ketika mengakses tingkat data yang dalam dalam rantai, sementara objek yang tidak dapat diubah tidak akan melaporkan kesalahan saat menghadapi situasi ini, dan pengembalian tidak terdefinisi.
Saat men -debug, jika Anda ingin melihat struktur internal objek yang tidak dapat diubah, disarankan untuk menggunakan TOJSON () untuk mengubahnya menjadi objek yang dapat berubah secara normal terlebih dahulu.