Module: util/sorted-stringify

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" is false a circular structure results in an error. However, if the parameter is set to true 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 as undefined.
  • In addition stringifies functions (relying on function object's toString() method), Map and Set objects, Error objects. To recreate the original objects a reviver function fill be needed for JSON.parse for these non-standard objects.
  • Map and Set 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 and Set 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:

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