Minulla on suuri objekti, jonka haluan muuntaa JSONiksi ja lähettää. Sillä on kuitenkin ympyrärakenne. Haluan heittää kaikki olemassa olevat ympyräviittaukset pois ja lähettää kaiken, mikä voidaan muuttaa merkkijonoksi. Miten se tehdään?
Kiitos.
var obj = {
a: "foo",
b: obj
}
Haluan stringify obj osaksi:
{"a":"foo"}
Käytä JSON.stringify
-ohjelmaa mukautetun korvaajan kanssa. Esimerkiksi:
// Demo: Circular reference
var circ = {};
circ.circ = circ;
// Note: cache should not be re-used by repeated calls to JSON.stringify.
var cache = [];
JSON.stringify(circ, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Duplicate reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
});
cache = null; // Enable garbage collection
Tämän esimerkin korvaaja ei ole 100-prosenttisesti oikea (riippuen "duplikaatin" määritelmästäsi). Seuraavassa tapauksessa arvo hylätään:
var a = {b:1}
var o = {};
o.one = a;
o.two = a;
// one and two point to the same object, but two is discarded:
JSON.stringify(o, ...);
Mutta konsepti pysyy voimassa: Käytä mukautettua korvaajaa ja pidä kirjaa analysoiduista objektiarvoista.
Tulevaisuuden googlaajille, jotka etsivät ratkaisua tähän ongelmaan, kun et tiedä kaikkien ympyräviittausten avaimia, voit käyttää JSON.stringify-funktion ympärillä olevaa käärekäsitettä ympyräviittausten poissulkemiseksi. Katso esimerkkiskripti osoitteessa https://gist.github.com/4653128.
Ratkaisu tiivistyy lähinnä siihen, että säilytetään viittaus aiemmin tulostettuihin objekteihin matriisissa ja tarkistetaan se korvaavassa funktiossa ennen arvon palauttamista. Se on rajoittavampi kuin pelkkä ympyräviittausten poissulkeminen, koska se estää myös sen, että objekti tulostetaan kahdesti, minkä yhtenä sivuvaikutuksena on ympyräviittausten välttäminen.
Esimerkki kääreestä:
function stringifyOnce(obj, replacer, indent){
var printedObjects = [];
var printedObjectKeys = [];
function printOnceReplacer(key, value){
var printedObjIndex = false;
printedObjects.forEach(function(obj, index){
if(obj===value){
printedObjIndex = index;
}
});
if(printedObjIndex && typeof(value)=="object"){
return "(see " + value.constructor.name.toLowerCase() + " with key " + printedObjectKeys[printedObjIndex] + ")";
}else{
var qualifiedKey = key || "(empty key)";
printedObjects.push(value);
printedObjectKeys.push(qualifiedKey);
if(replacer){
return replacer(key, value);
}else{
return value;
}
}
}
return JSON.stringify(obj, printOnceReplacer, indent);
}
Käytä JSON.stringify-menetelmää korvaajan kanssa. Lue lisätietoja tästä dokumentaatiosta. http://msdn.microsoft.com/en-us/library/cc836459%28v=vs.94%29.aspx
var obj = {
a: "foo",
b: obj
}
var replacement = {"b":undefined};
alert(JSON.stringify(obj,replacement));
Keksi tapa täyttää korvausmatriisi syklisillä viittauksilla. Voit käyttää typeof-metodia selvittääksesi, onko ominaisuus 'object' -tyyppinen ( viittaus ) ja tarkkaa tasa-arvotarkastusta ( === ) varmistaaksesi ympyräviittauksen.