I\'ve not seen (yet?) JSON.stringify
to be non-deterministic in Node.JS.
There is no guarantee it to be deterministic on the specification level.
To clarify jmrk's answer;
According to the spec, integer keys are serialized in numeric order and non-integer keys in chronological order of property creation, e.g.;
var o = {};
o[2] = 2;
o.a = 3;
o.b = 4;
o["1"] = 1;
assert(JSON.stringify(o)==='{"1":1,"2":2,"a":3,"b":4}');
Therefore following assertion is guaranteed to be true
if( obj1 === obj2 ) {
assert(JSON.stringify(obj1) === JSON.stringify(obj2));
}
but two "deep equal" objects may be serialized into different strings;
var obj1 = {};
obj1["a"] = true;
obj1["b"] = true;
assert(JSON.stringify(obj1)==='{"a":true,"b":true}');
var obj2 = {};
obj2["b"] = true;
obj2["a"] = true;
assert(JSON.stringify(obj2)==='{"b":true,"a":true}');
Spec quote;
- Let keys be a new empty List.
For each own property key P of O that is an integer index, in ascending numeric index order, do
a. Add P as the last element of keys.
For each own property key P of O that is a String but is not an integer index, in ascending chronological order of property creation, do
a. Add P as the last element of keys.
For each own property key P of O that is a Symbol, in ascending chronological order of property creation, do
a. Add P as the last element of keys.
- Return keys.
From https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys