V8 中 JSON.stringify() 是确定性的吗?

2024-01-04

我还没见过(还没?)JSON.stringifyNode.JS 中的不确定性。

不能保证它在规范级别上具有确定性。

但是V8呢? 它的实现是确定性的吗? 是否能保证它在未来的 V8 版本中保持确定性?

Edit:

对于确定性,我的意思是无论以下断言的值是什么,都是正确的json_str是。 (假设该值是有效的 JSON 字符串。)

const obj = JSON.parse(json_str);
assert(JSON.stringify(obj)===JSON.stringify(obj)); // always true

Edit 2:

实际上,我也对以下断言是否正确感兴趣

if( deepEqual(obj1, obj2) ) {
    assert(JSON.stringify(obj1)===JSON.stringify(obj2))
}

事实并非如此(参见答案)。


澄清jmrk的答案;

根据规范,整数键按数字顺序序列化,非整数键按属性创建的时间顺序序列化,例如;

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}');

因此以下断言保证为真

if( obj1 === obj2 ) {
  assert(JSON.stringify(obj1) === JSON.stringify(obj2));
}

但两个“深度相等”的对象可能会被序列化为不同的字符串;

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}');

规格报价;

  1. 让keys成为一个新的空列表。
  2. 对于 O 的每个自己的属性键 P(作为整数索引),按升序数字索引顺序,执行

    A。添加 P 作为键的最后一个元素。

  3. 对于 O 的每个自己的属性键 P(它是字符串但不是整数索引),按照属性创建的升序时间顺序,执行以下操作:

    A。添加 P 作为键的最后一个元素。

  4. 对于作为 Symbol 的 O 的每个自己的属性键 P,按照属性创建的升序时间顺序,执行

    A。添加 P 作为键的最后一个元素。

  5. 返回键。

From https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

V8 中 JSON.stringify() 是确定性的吗? 的相关文章

随机推荐