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

我还没有看到(还?) JSON.stringify在Node.JS中是非确定性的。

不能保证它在规格级别上是确定性的。

但是V8呢? 它的实现是否具有确定性? 有没有保证它为未来的V8版本保持确定性?

编辑:

对于确定性,我的意思是,无论json_str的值是什么,下面的断言都是正确的。 (给定值是一个有效的JSONstring。)

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

编辑2:

其实,我也有兴趣下面的说法是真实的

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

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

如果通过“确定性”,则表示对象属性的枚举顺序:实际指定的顺序,V8遵循规范。 请参阅https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys 。 [编辑:这是你澄清定义的答案,所以是的,JSON.stringify在这个意义上是确定性的。]

如果通过“确定性”来表示“总是为同一个input对象返回相同的string”,那么,没有:-)

 > var o = { toJSON: function() { return Math.random(); } } > JSON.stringify(o); < "0.37377773963616434" > JSON.stringify(o); < "0.8877065604993732" 

Proxy对象和JSON.stringify参数也可以用来创build任意行为(尽pipeJSON.stringify本身总是做同样的事情)。

如果通过“确定性”你的意思是别的,请说明。

澄清jmrk的答案;

根据规范,整数键是按照数字顺序和非整数键按时间顺序创build的,例如:

 var o = {}; o[2] = 2; oa = 3; ob = 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)); } 

但是两个“深度相等”的对象可能被串行化成不同的string;

 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. 让键是一个新的空列表。
  2. 对于作为整数索引的O的每个属性关键字P,按升序数字索引顺序do

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

  3. 对于属于stringO但不是整数索引的O的每个属性关键字P,按照时间顺序创build属性,

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

  4. 对于作为符号的O的各自己的财产关键字P,按照财产创造的时间顺序排列

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

  5. 返回键。

https://tc39.github.io/ecma262/#sec- Ordinownpropertykeys

您的判断主义归结为:

  1. Order =>对象数据是否以相同的顺序编组?

是的,遍历对象数据总是在同一个“路由”中发生。

  1. 内容=>将对象数据封送到相同的内容?

是的,除非通过toJSON引入的任意性覆盖了上面解释的@jmrk。

  1. 并发性=>对象数据是否在检查之间被修改?

不,V8脚本运行器是单线程的,所以没有混乱的访问发生。

  1. 规范=>规范中是否存在违反决定论的条款?

不,除了上下文replace/覆盖,parsing器和string应该每次都产生相同的数据。

  1. Compatibility =>所有的stringify方法是否会产生兼容的数据?

不,规范并没有清楚列出对象字段的顺序,因此实现可以自由地遍历对象,这意味着数据可能与“目的”和“精神”相同,而不是可比较的字节到字节。

希望这可以帮助!