Dalam Javascript, apakah ada cara untuk membuat tiruan copy-on-write suatu objek?

Masalah: Saya sedang menulis ulang fungsi yang mengembalikan objek javascript biasa yang besar. Objek asli tidak boleh diubah oleh pemanggil. Fungsi tersebut saat ini dipanggil oleh ratusan penelepon.

Beberapa solusi:

  • Kembalikan salinan objek yang dalam. Ini adalah solusi saat ini. Hal ini buruk karena (a) objeknya sangat besar, dan (b) 90% kloning tidak diperlukan karena sebagian besar pemanggil tidak mengubah nilainya.
  • Mengembalikan referensi ke objek. Ini buruk karena penelepon dapat mengubah objek asli, yang tidak saya inginkan.
  • Kembalikan referensi dengan Object.freeze atau yang serupa. Ini mungkin berhasil jika saya dapat menjamin bahwa penelepon tidak mencoba mengubah nilai pengembalian. Tapi saya tidak bisa menjamin hal ini. Sekali lagi, fungsi tersebut dipanggil oleh ratusan pemanggil, dan banyak yang sudah mengubah nilainya (klon dari).

Yang saya inginkan adalah solusi copy-on-write yang memiliki dua properti berikut:

  1. Nilai yang dikembalikan dari fungsi tersebut adalah referensi ke objek asli hingga nilainya diubah.
  2. Setelah nilainya diubah, nilainya menjadi klon dalam dari objek aslinya.

Saya melakukan beberapa tes dan saya dapat menerapkannya menggunakan Javascript Proxy. Cukup jebak semua operasi yang mengubah target (yaitu set, deleteProperty, defineProperty, dll.) untuk mendengarkan perubahan. Kemudian jebakan pada get untuk mengembalikan referensi jika tidak ada perubahan yang dilakukan, dan mengembalikan klon jika ada perubahan. Proksi juga harus menjadi proksi mendalam untuk mendengarkan perubahan pada properti yang disarangkan.

Meskipun saya bisa menerapkannya sendiri, saya bertanya-tanya apakah sudah ada implementasinya. Saya lebih suka tidak menemukan kembali roda jika tidak perlu. Kompatibilitas browser bagus, tapi tidak penting.


person Some Guy    schedule 15.02.2020    source sumber
comment
Sepertinya cow adalah yang Anda perlukan npmjs.com/package/cow   -  person artanik    schedule 15.02.2020
comment
@artanik hmmm...ini terlihat menjanjikan. Terima kasih!   -  person Some Guy    schedule 16.02.2020
comment
Sudahkah Anda mencoba paket immer   -  person Aswin    schedule 18.10.2020


Jawaban (1)


Perpustakaan immer melakukan persis seperti yang Anda gambarkan - mengimplementasikan COW menggunakan proxy JavaScript. Lihat dokumennya di sini: https://immerjs.github.io/immer/

person Nir    schedule 08.05.2021