2017-02-27 53 views
1

我還沒有看到(還?)JSON.stringify在Node.JS中是非確定性的。JSON.stringify()在V8中是確定性的嗎?

無法保證它在規格級別上是確定性的。

但是V8怎麼樣; 它的實現有確定性嗎? 有沒有保證它能夠保持未來版本的V8的確定性?

編輯:

確定性我的意思是下面的說法是真實的,不管什麼json_str值。 (給定的值是一個有效的JSON字符串。)

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

這是不案例(見答案)。

+1

確定性在什麼意義到底是什麼?目前還不清楚你在這裏問的是什麼。謝謝你澄清。 –

+0

請參閱編輯,感謝您的評論。 – brillout

回答

4

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

Spec quote;

  1. 讓鍵爲新的空列表。
  2. 鄰的每個自己的財產密鑰P是一個整數指數,在上升的數字索引順序,執行

    一個。將P添加爲鍵的最後一個元素。

  3. 鄰的每一個自己的財產P鍵是一個字符串,但不是整數指數,上升的創造的時間順序,做

    一個。將P添加爲鍵的最後一個元素。

  4. 鄰的每一個自己的財產P鍵是一個符號,在提升性能的創作時間順序,做

    一個。將P添加爲鍵的最後一個元素。

  5. 返回鍵。

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

5

如果通過「確定性」指對象屬性的枚舉順序:實際指定,V8遵循規範。見https://tc39.github.io/ecma262/#sec-ordinaryownpropertykeys。 [編輯:這是你澄清的定義的答案,所以是的,JSON.stringify是確定性的。]

如果通過「確定性」你的意思是「總是返回相同的輸入對象相同的字符串」,然後,嗯,沒有:-)

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

Proxy對象和replacer參數JSON.stringify也可以用來創建任意行爲(即使JSON.stringify本身總是做同樣的事情)。

如果通過「確定性」您的意思是別的,請註明。

+0

OrdinaryOwnPropertyKeys /你的鏈接如何與JSON.stringify相關?實際上,我沒有看到https://tc39.github.io/ecma262/#sec-json.stringify中指定的任何枚舉順序。至於我的確定性意思,請參閱OP編輯。 – brillout

+1

按照鏈接:JSON。stringify - > SerializeJSONProperty - > SerializeJSONObject - > EnumerableOwnProperties - > [[OwnPropertyKeys]] - > OrdinaryOwnPropertyKeys。您澄清的定義恰恰相當於此。 – jmrk

+0

好的整潔,謝謝 – brillout

2

確定性在你的條件歸結爲以下:

  1. 訂單=>將對象數據以相同的順序被封?

是的,遍歷對象數據總是在同一個'路由'中發生。

  1. Content =>對象數據是否會封送相同的內容?

是的,除非通過toJSON引入的任意性覆蓋了上面解釋的@jmrk。

  1. 併發性=>對象數據是否在檢查之間被修改?

不,V8腳本運行器是單線程的,所以沒有混亂的訪問發生。

  1. Specification =>規範中是否存在違反決定論的條款?

不,除了上下文替換/覆蓋,解析器和字符串化應該每次都產生相同的數據。

  1. Compatibility =>所有的stringify方法都會產生兼容的數據嗎?

不,規範不清楚列表的順序對象字段,所以實現可以自由地遍歷對象,這意味着數據可能與'目標'和'精神'相同,而不是可比較的字節-字節。

希望這會有所幫助!