Berikut adalah contoh dari struktur data dengan referensi siklik:
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
Ketika Anda ingin MENJAGA referensi siklik (kembalikan ketika Anda deserialize, daripada "nuking" mereka), Anda memiliki 2 pilihan, yang akan saya bandingkan di sini. Pertama adalah cycle.js Douglas Crockford , kedua adalah paket siberia saya . Keduanya bekerja dengan terlebih dahulu "mendekomposisi" objek, yaitu, membangun objek lain (tanpa referensi siklik) "yang mengandung informasi yang sama."
Mr. Crockford lebih dulu:
JSON.decycle(makeToolshed())
Seperti yang Anda lihat, struktur bersarang JSON dipertahankan, tetapi ada hal baru, yaitu objek dengan $ref
properti khusus . Mari kita lihat cara kerjanya.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
Tanda dolar berarti root. .bolt
Setelah $ref
memberitahu kita bahwa itu .bolt
adalah objek "sudah terlihat", dan nilai properti khusus itu (di sini, string $ ["nut"] ["needs"]) memberi tahu kita di mana, lihat pertama di ===
atas. Begitu juga untuk yang kedua $ref
dan yang kedua di ===
atas.
Mari kita gunakan tes kesetaraan mendalam yang sesuai (yaitu deepGraphEqual
fungsi Anders Kaseorg dari jawaban yang diterima untuk pertanyaan ini ) untuk melihat apakah kloning bekerja.
root = makeToolshed();
clone = JSON.retrocycle(JSON.decycle(root));
deepGraphEqual(root, clone) // true
serialized = JSON.stringify(JSON.decycle(root));
clone2 = JSON.retrocycle(JSON.parse(serialized));
deepGraphEqual(root, clone2); // true
Sekarang, siberia:
JSON.Siberia.forestify(makeToolshed())
Siberia tidak mencoba meniru JSON "klasik", tanpa struktur bersarang. Grafik objek dijelaskan dengan cara "datar". Setiap node dari objek grafik berubah menjadi flat tree (daftar pasangan nilai kunci biasa dengan nilai integer-only), yang merupakan entri di .forest.
Pada indeks nol, kami menemukan objek root, pada indeks yang lebih tinggi, kami menemukan node lain dari grafik objek, dan nilai-nilai negatif (dari beberapa kunci dari beberapa pohon hutan) menunjuk ke atoms
array, (yang diketik melalui array jenis, tetapi kami akan melewatkan detail pengetikan di sini). Semua node terminal ada di tabel atom, semua node non-terminal ada di tabel hutan, dan Anda dapat melihat langsung berapa banyak node yang dimiliki grafik objek, yaitu forest.length
. Mari kita coba jika berhasil:
root = makeToolshed();
clone = JSON.Siberia.unforestify(JSON.Siberia.forestify(root));
deepGraphEqual(root, clone); // true
serialized = JSON.Siberia.stringify(JSON.Siberia.forestify(root));
clone2 = JSON.Siberia.unforestify(JSON.Siberia.unstringify(serialized));
deepGraphEqual(root, clone2); // true
perbandingan
akan menambahkan bagian nanti.