javascript जेएसओएन ने इन्फिनिटी और नाएन छोड़ा; ईसीएमएस्क्रिप्ट में JSON स्थिति?




ecma262 (7)

Infinity और NaN कीवर्ड या कुछ खास नहीं हैं, वे वैश्विक वस्तु (जैसे undefined ) पर गुण हैं और इस तरह बदला जा सकता है। यही कारण है कि जेएसओएन ने उन्हें spec में शामिल नहीं किया है - संक्षेप में यदि आप eval(jsonString) या JSON.parse(jsonString) करते हैं तो किसी भी वास्तविक JSON स्ट्रिंग का एक ही परिणाम EcmaScript में होना चाहिए।

अगर इसकी अनुमति थी तो कोई व्यक्ति कोड को इंजेक्ट कर सकता था

NaN={valueOf:function(){ do evil }};
Infinity={valueOf:function(){ do evil }};

एक मंच (या जो कुछ भी) में और फिर उस साइट पर किसी भी जेसन उपयोग से समझौता किया जा सकता है।

कोई विचार क्यों JSON ने NaN और +/- अनंतता छोड़ी? यह अजीब परिस्थिति में जावास्क्रिप्ट रखता है जहां ऑब्जेक्ट्स अन्यथा धारावाहिक होते हैं, अगर वे NaN या +/- अनंत मान रखते हैं।

ऐसा लगता है कि इसे पत्थर में डाला गया है: RFC4627 और ECMA-262 (धारा 24.3.2, JSON.stringify, नोट 4, अंतिम संपादन पर पृष्ठ 507 देखें):

सीमित संख्याएं जैसे कि ToString(number) कॉल करके ToString(number) । साइन के बावजूद NaN और अनंतता स्ट्रिंग null रूप में दर्शायी जाती है।


यदि आपके पास सीरियलाइजेशन कोड तक पहुंच है तो आप इन्फिनिटी को 1.0e + 1024 के रूप में प्रदर्शित कर सकते हैं। एक्सपोनेंट एक डबल में प्रतिनिधित्व करने के लिए बहुत बड़ा है और जब deserialized यह अनंतता के रूप में प्रतिनिधित्व किया जाता है। वेबकिट पर काम करता है, अन्य जेसन पार्सर्स के बारे में अनिश्चित!


यदि मेरे जैसा आप धारावाहिक कोड पर कोई नियंत्रण नहीं रखते हैं, तो आप नाक के कुछ हिस्सों को नाक या किसी अन्य मूल्य के साथ बदलकर नाक मानों से निपट सकते हैं:

$.get("file.json", theCallback)
.fail(function(data) {
  theCallback(JSON.parse(data.responseText.replace(/NaN/g,'null'))); 
} );

संक्षेप में, जब मूल जेसन पार्सर एक अवैध टोकन का पता लगाता है तो .fail कॉल किया जाएगा। फिर अमान्य टोकन को प्रतिस्थापित करने के लिए एक स्ट्रिंग प्रतिस्थापन का उपयोग किया जाता है। मेरे मामले में यह serialiser के लिए NaN मान वापस करने के लिए एक अपवाद है, इसलिए यह विधि सबसे अच्छा तरीका है। यदि परिणाम में सामान्य रूप से अमान्य टोकन होता है तो आप $ .get का उपयोग न करने के लिए बेहतर होंगे, लेकिन JSON परिणाम मैन्युअल रूप से पुनर्प्राप्त करने और हमेशा स्ट्रिंग प्रतिस्थापन को चलाने के लिए।


क्या आप शून्य ऑब्जेक्ट पैटर्न को अनुकूलित कर सकते हैं, और आपके JSON में ऐसे मानों का प्रतिनिधित्व करते हैं

"myNum" : {
   "isNaN" :false,
   "isInfinity" :true
}

फिर जांच करते समय, आप प्रकार की जांच कर सकते हैं

if (typeof(myObj.myNum) == 'number') {/* do this */}
else if (myObj.myNum.isNaN) {/* do that*/}
else if (myObj.myNum.isInfinity) {/* Do another thing */}

मुझे जावा में पता है कि आप ऐसी चीज को लागू करने के लिए क्रमबद्ध तरीकों को ओवरराइड कर सकते हैं। सुनिश्चित नहीं है कि आपका सीरियलाइजिंग कहां से है, इसलिए मैं धारावाहिक तरीकों में इसे कार्यान्वित करने के तरीके के बारे में विवरण नहीं दे सकता।


स्ट्रिंग्स "इन्फिनिटी", "-इफिनिटी", और "नाएन" जेएस में अपेक्षित मूल्यों के लिए सभी कॉरर्स हैं। इसलिए मैं जेएसओएन में इन मानों का प्रतिनिधित्व करने का सही तरीका तर्क दूंगा।

> +"Infinity"
Infinity

> +"-Infinity"
-Infinity

> +"NaN"
NaN

यह सिर्फ एक शर्म की बात है JSON.stringify डिफ़ॉल्ट रूप से ऐसा नहीं करता है। लेकिन एक तरीका है:

> JSON.stringify({ x: Infinity }, function (k,v) { return v === Infinity ? "Infinity" : v; })
"{"x":"Infinity"}"

ऐसा इसलिए हो सकता है क्योंकि जेएसओएन का उद्देश्य डेटा इंटरचेंज प्रारूप होना है जिसका उपयोग विभिन्न प्लेटफार्मों में किया जा सकता है और नाएन / इन्फिनिटी इसे कम पोर्टेबल बना देगा।


मूल प्रश्न पर: मैं उपयोगकर्ता "cbare" से सहमत हूं कि यह JSON में एक दुर्भाग्यपूर्ण चूक है। आईईईई 754 इन्हें फ्लोटिंग पॉइंट नंबर के तीन विशेष मानों के रूप में परिभाषित करता है। इसलिए जेएसओएन आईईईई 754 फ्लोटिंग पॉइंट नंबरों का पूरी तरह से प्रतिनिधित्व नहीं कर सकता है। यह वास्तव में और भी बदतर है, क्योंकि ईएसएमए 262 5.1 में परिभाषित जेएसओएन यह भी परिभाषित नहीं करता है कि इसकी संख्या आईईईई 754 पर आधारित है या नहीं। चूंकि ECMA262 में स्ट्रिफ़ाई () फ़ंक्शन के लिए वर्णित डिज़ाइन प्रवाह में तीन विशेष आईईईई मानों का उल्लेख किया गया है, इसलिए कोई संदेह कर सकता है कि इरादा वास्तव में आईईईई 754 फ्लोटिंग पॉइंट नंबरों का समर्थन करने के लिए था।

एक अन्य डेटा बिंदु के रूप में, प्रश्न से असंबंधित: एक्सएमएल डेटाटाइप xs: फ्लोट और एक्सएस: डबल यह बताता है कि वे आईईईई 754 फ्लोटिंग पॉइंट नंबर पर आधारित हैं, और वे इन तीन विशेष मूल्यों के प्रतिनिधित्व का समर्थन करते हैं (डब्ल्यू 3 सी एक्सएसडी 1.0 भाग 2 देखें , जानकारी का प्रकार)।





ecma262