Döngüsel referansları olan bir veri yapısı örneği:
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
Döngüsel referansları TUTMAK istediğinizde ("nuking" yerine serileştirdiğinizde geri yükleyin), burada karşılaşacağım 2 seçeneğiniz var. Birincisi Douglas Crockford'un cycle.js , ikincisi sibirya paketim. Her ikisi de önce nesneyi "çözerek", yani aynı bilgiyi içeren başka bir nesne (döngüsel referanslar olmadan) oluşturarak çalışır.
Bay Crockford önce gidiyor:
JSON.decycle(makeToolshed())
Gördüğünüz gibi, JSON'un iç içe yapısı korunur, ancak özel bir $ref
özelliğe sahip nesneler olan yeni bir şey vardır . Bunun nasıl çalıştığını görelim.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
Dolar işareti kök anlamına gelir. .bolt
sahip $ref
olduğunu söyler .bolt
bir "zaten görmüş" nesnedir ve ilk gördüğünüz yerde bu özel mülkiyet değeri (burada, dize $ [ "somun"] [ "ihtiyaçlar"]) söyler ===
yukarıda. Aynı şekilde ikinci $ref
ve ikinci için de ===
.
Klonlamanın işe yarayıp yaramadığını görmek için uygun bir derin eşitlik testi (yani Anders Kaseorg'un bu soruyadeepGraphEqual
kabul edilen cevaptan işlevi) kullanalım .
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
Şimdi, sibirya:
JSON.Siberia.forestify(makeToolshed())
Sibirya "klasik" JSON, iç içe bir yapı taklit etmeye çalışmaz. Nesne grafiği "düz" bir şekilde tarif edilir. Nesne grafiğinin her düğümü düz bir ağaca dönüştürülür (yalnızca tamsayı değerlere sahip düz anahtar değer çifti listesi). .forest.
Bu, dizin sıfırında kök nesneyi buluruz, daha yüksek endekslerde, nesne grafiği ve negatif değerler (ormanın bir ağacının bazı anahtarlarının) atoms
diziyi işaret eder (türler dizisi aracılığıyla yazılır, ancak buraya yazma ayrıntılarını atlayacağız). Tüm terminal düğümleri atom tablosunda, terminal olmayan tüm düğümler orman tablosundadır ve nesne grafiğinin kaç düğümü olduğunu hemen görebilirsiniz forest.length
. Çalışıp çalışmadığını test edelim:
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
karşılaştırma
bölümü daha sonra ekleyecektir.