4 ![Downloads](https://img.shields.io/npm/dm/circular-json.svg) [![Build Status](https://travis-ci.org/WebReflection/circular-json.svg?branch=master)](https://travis-ci.org/WebReflection/circular-json) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/circular-json/badge.svg?branch=master)](https://coveralls.io/github/WebReflection/circular-json?branch=master) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/WebReflection/donate)
6 Serializes and deserializes otherwise valid JSON objects containing circular references into and from a specialized JSON format.
10 ### A Working Solution To A Common Problem
18 object.arr.push(object.arr);
21 var serialized = CircularJSON.stringify(object);
22 // '{"arr":["~","~","~arr"],"obj":"~"}'
23 // NOTE: CircularJSON DOES NOT parse JS
24 // it handles receiver and reviver callbacks
26 var unserialized = CircularJSON.parse(serialized);
27 // { arr: [ [Circular], [Circular] ],
30 unserialized.obj === unserialized;
31 unserialized.arr[0] === unserialized;
32 unserialized.arr.pop() === unserialized.arr;
37 * uses `~` as a special prefix symbol to denote which parent the reference belongs to (i.e. `~root~child1~child2`)
38 * reasonably fast in both serialization and deserialization
39 * compact serialization for easier and slimmer transportation across environments
40 * [tested and covered](test/circular-json.js) over nasty structures too
41 * compatible with all JavaScript engines
43 Node Installation & Usage
47 npm install --save circular-json
54 CircularJSON = require('circular-json'),
60 str = CircularJSON.stringify(obj);
63 There are no dependencies.
65 Browser Installation & Usage
68 * Global: <build/circular-json.js>
69 * AMD: <build/circular-json.amd.js>
70 * CommonJS: <build/circular-json.node.js>
72 (generated via [gitstrap](https://github.com/WebReflection/gitstrap))
75 <script src="build/circular-json.js"></script>
81 var CircularJSON = window.CircularJSON
82 , obj = { foo: 'bar' }
87 str = CircularJSON.stringify(obj);
90 NOTE: Platforms without native JSON (i.e. MSIE <= 8) requires `json3.js` or similar.
92 It is also *a bad idea* to `CircularJSON.parse(JSON.stringify(object))` because of those manipulation used in `CircularJSON.stringify()` able to make parsing safe and secure.
94 As summary: `CircularJSON.parse(CircularJSON.stringify(object))` is the way to go, same is for `JSON.parse(JSON.stringify(object))`.
99 It's the same as native JSON, except the fourth parameter `placeholder`, which circular references to be replaced with `"[Circular]"` (i.e. for logging).
101 * CircularJSON.stringify(object, replacer, spacer, placeholder)
102 * CircularJSON.parse(string, reviver)
104 Bear in mind `JSON.parse(CircularJSON.stringify(object))` will work but not produce the expected output.
109 ### Why Not the [@izs](https://twitter.com/izs) One
110 The module [json-stringify-safe](https://github.com/isaacs/json-stringify-safe) seems to be for `console.log()` but it's completely pointless for `JSON.parse()`, being latter one unable to retrieve back the initial structure. Here an example:
113 // a logged object with circular references
115 "circularRef": "[Circular]",
121 // what do we do with above output ?
124 Just type this in your `node` console: `var o = {}; o.a = o; console.log(o);`. The output will be `{ a: [Circular] }` ... good, but that ain't really solving the problem.
126 However, if that's all you need, the function used to create that kind of output is probably faster than `CircularJSON` and surely fits in less lines of code.
129 ### Why Not {{put random name}} Solution
130 So here the thing: circular references can be wrong but, if there is a need for them, any attempt to ignore them or remove them can be considered just a failure.
132 Not because the method is bad or it's not working, simply because the circular info, the one we needed and used in the first place, is lost!
134 In this case, `CircularJSON` does even more than just solve circular and recursions: it maps all same objects so that less memory is used as well on deserialization as less bandwidth too!
135 It's able to redefine those references back later on so the way we store is the way we retrieve and in a reasonably performant way, also trusting the snappy and native `JSON` methods to iterate.