- Source:
Methods
(static) stringify(obj) → {string}
Parameters:
Name | Type | Description |
---|---|---|
obj |
* | A value or an object. |
A deterministic version of JSON.stringify
that always creates the exact same string for the
same data. It also handles Map and Set objects for which the native method returns an empty
object "{}" by converting them to arrays.
Features
- Circle detection: By default and if the 2nd parameter "
convertCircles
" isfalse
a circular structure results in an error. However, if the parameter is set totrue
circles will be converted into meta-information inside the JSON string. This can be used either for debug or error output, where a circle should be reported rather than preventing all output, or it can be used by a recipient to recreate the circle when reviving an object from the JSON string. - Determinism is achieved by sorting object keys instead of using the natural Javascript iteration sequence determined by property insertion order.
- Supports everything native
JSON.stringify
does, except that... - Like
JSON.stringify
, ES 2015 symbols are not supported, but unlike the standard method ours will throw an error when encountering a symbol instead of quietly treating it asundefined
. - In addition stringifies functions (relying on function object's
toString()
method),Map
andSet
objects,Error
objects. To recreate the original objects a reviver function fill be needed forJSON.parse
for these non-standard objects. Map
andSet
objects are simply represented as arrays, so the reviver function will have to know which properties are of those types. This stringifier does not add any meta information that a reviver could use to learn about such types. Since the main purpose of this function is to stringify values of ONE objects for microdata representation this is good enough. The reviver can (and does) use the type information in the ONE object recipes.- Insertion order is lost: The array representation of
Map
andSet
will be sorted (each array item's string representation is used for this). The keys of objects being stringified are sorted as well. This is to solve the problem that the array representation is insertion-order dependent even though Map and Set objects are unordered, because iteration order of objects in Javascript respects insertion order. This means that any code relying on maintaining the original insertion order will fail! - Just like
JSON.stringify
, only enumerable properties are included.
Performance
Testing on node.js 7.10 showed this function takes about twice as long as the native method. On IE Edge and on Firefox 53 it took 10 times as long or worse. For comparison:
- Package https://github.com/Kikobeats/json-stringify-deterministic took over five times as long as this code.
- Package https://github.com/substack/json-stable-stringify took more than twice as long.
See https://abdulapopoola.com/2017/02/27/what-you-didnt-know-about-json-stringify/ for information about some idiosyncrasies of JSON conversion in JavaScript.
- Source:
Throws:
-
Throws an error if a circle is detected or if a Function, Promise or Symbol is detected.
-
Type: Error
Returns:
Returns a JSON string
Type: string
(static) stringifyWithCircles(obj) → {string}
Parameters:
Name | Type | Description |
---|---|---|
obj |
* | A value or an object. |
Same as stringify, but when a circle is detected it is meta-encoded in the JSON string result instead of throwing an error. Recreating the original object from that JSON string will require a special reviver that uses the metadata to recreate the circle. The main use case though is when this stringifier is used to create readable string output for errors messages or for debugging. In those cases knowing that there is a circle is infinitely better than getting another error from inside the original error because some object that was meant to be part of the error message cold not be stringified because of a circle.
- Source:
Returns:
Returns a JSON string
Type: string