2012-02-07 25 views
6

मैं एक सरणी की तरह उद्देश्य यह है कि एक सरणी वस्तु के रूप में घोषित किया गया था और पाया stringify करने की कोशिश कर रहा था JSON.stringify सही ढंग से प्रसंस्करण नहीं किया गया था कि सरणी जैसी वस्तु है जब यह एक के रूप में परिभाषित किया गया है सरणी वस्तु।जावास्क्रिप्ट सरणी वस्तु वस्तुओं की तरह सरणी बनाम - स्पष्टीकरण

अधिक स्पष्टता के लिए नीचे देखें, ->jsFiddle

var simpleArray = []; //note that it is defined as Array Object 

alert(typeof simpleArray); // returns object -> Array Object 

simpleArray ['test1'] = 'test 1'; 
simpleArray ['test2'] = 'test 2'; 

alert(JSON.stringify(simpleArray)); //returns [] 

यह ठीक काम किया है और मुझे {"test1":"test 1","test2":"test 2"} लौटे जब मैं var simpleArray = {}; को

var simpleArray = []; बदल दिया है।

क्या कोई कुछ प्रकाश या कुछ संदर्भ छोड़ सकता है जहां मैं और पढ़ सकता हूं?

संपादित करें:

प्रश्न: जब typeof simpleArray = [] और simpleArray = {} लौटे वस्तु, क्यों JSON.stringify दोनों ही मामलों में {"test1":"test 1","test2":"test 2"} लौटने में सक्षम नहीं था?

उत्तर

2

आप एक सरणी नहीं चाहते हैं। जब आप जावास्क्रिप्ट में "एसोसिएटिव सरणी" चाहते हैं, तो आप वास्तव में एक ऑब्जेक्ट चाहते हैं, {}

आप उन्हें instanceof Array साथ भेद कर सकते हैं:

[] instanceof Array // true 
({}) instanceof Array // false 

संपादित करें: यह इसे संसाधित कर सकते हैं। यह सरणी के सभी तत्वों को क्रमबद्ध करता है। हालांकि, एक तत्व होने के लिए, एक संख्यात्मक कुंजी होना चाहिए। इस मामले में, कोई नहीं है।

यह JSON के लिए अद्वितीय नहीं है। यह toSource और length संपत्ति के साथ संगत है।

+0

मैं उस हिस्से को समझता हूं, जो मैं जानना चाहता था वह है कि JSON.stringify क्यों घोषित नहीं किया जा सकता है []। –

+0

धन्यवाद! मैं उदाहरण के लिए देख रहा था। मैं टाइपफॉफ़ का उपयोग करने की कोशिश कर रहा था जो दोनों मामलों में ऑब्जेक्ट लौटा रहा था। –

+1

ईएस 5 के बाद भी 'Array.isArray (...) '(15.4.3.2) है जो इसके विपरीत फ्रेम-सुरक्षित है। इसे नकल किया जा सकता है। – PointedEars

4

अंतर सूचकांक है। जब आप एक सरणी [] का उपयोग करते हैं तो अनुक्रमणिका केवल सकारात्मक पूर्णांक हो सकती है।

तो निम्नलिखित गलत है:

क्योंकि test1
var array = [ ]; 
array['test1'] = 'test 1'; 
array['test2'] = 'test 2'; 

और test2 पूर्णांकों नहीं हैं।

var array = [ ]; 
array[0] = 'test 1'; 
array[1] = 'test 2'; 

या यदि आप एक जावास्क्रिप्ट वस्तु की घोषणा तो गुण किसी भी तार हो सकता है: आदेश इसे ठीक करने में आप पूर्णांक आधारित अनुक्रमित उपयोग करने की आवश्यकता

:

var array = { }; 
array['test1'] = 'test 1'; 
array['test2'] = 'test 2'; 

के बराबर है जो

var array = { }; 
array.test1 = 'test 1'; 
array.test2 = 'test 2'; 
+0

तो क्या होता है जब आप 'var simpleArray = [] करते हैं; simpleArray ['test2'] = 'test 2'; '? –

+3

@ मैटफ़ेनविक, क्या होता है कि आप क्या उम्मीद कर सकते हैं इसके विपरीत: 'simpleArray.length = 0' जिसका अर्थ है कि इस सरणी में कोई तत्व नहीं है। आपके द्वारा परिभाषित संपत्ति तक पहुंचने के लिए आप अभी भी 'simpleArray.test2' का उपयोग कर सकते हैं। यह सिर्फ भ्रमित कोड है जिसे टालना चाहिए। विस्तृत स्पष्टीकरण के लिए –

+0

+1 लेकिन, जो मैं जानना चाहता था वह है कि JSON.stringify को [] के रूप में घोषित किए जाने पर क्यों संसाधित नहीं किया जा सका। मैंने टाइपफ का उपयोग करने की कोशिश की और यह मुझे दोनों मामलों में वस्तु वापस कर दिया। मैं इसे अपने प्रश्न में जोड़ने जा रहा हूं। –

1

जब JSON.stringify एक सरणी का सामना करना पड़ता है, यह एक समान तरीके से एक for पाश को 0 से simpleArray.length के मूल्यों को खोजने के iterates। उदाहरण के लिए:

var a = []; 
a[5] = "abc"; 
alert(JSON.stringify(a)); // alerts [null,null,null,null,null,"abc"] 

इसलिए इस पर गुण सेट करना JSON के लिए पूरी तरह से अदृश्य हो जाएगा।

हालांकि {} के साथ ऑब्जेक्ट को परिभाषित करने से जेएसओएन इसे किसी ऑब्जेक्ट के रूप में मानता है, और इसलिए यह ऑब्जेक्ट के गुणों (प्रोटोटाइप श्रृंखला से विरासत गुणों को छोड़कर) पर लूप करता है। इस तरह से यह आपके test1 और test2 गुणों को पा सकता है, और सफलतापूर्वक लौटाता है जो आप उम्मीद करते हैं।

2

"क्या कोई कुछ प्रकाश या कुछ संदर्भ छोड़ सकता है जहां मैं और पढ़ सकता हूं?"

जब आप JSON डेटा के साथ काम कर रहे हैं, आप json.org का उल्लेख विनिर्देश की आवश्यकताओं के बारे में पढ़ने के लिए कर सकते हैं।

JSON में, Array, से अलग मूल्यों की ऑर्डर सूची है।

enter image description here

तो JSON.stringify() बस कुछ भी है कि एक साधारण आदेश दिया सूची के रूप में प्रतिनिधित्व नहीं किया जा सका अनदेखी कर रहा है।

तो अगर आप ऐसा करेंगे ...

var simpleArray = []; 
simpleArray.foo = 'bar'; 

... आप अभी भी एक सरणी दे रहे हैं, तो यह केवल संख्यात्मक सूचकांक उम्मीद कर रही है, और कुछ और अनदेखी।

क्योंकि JSON भाषा स्वतंत्र है, JSON के साथ काम करने के तरीकों के बारे में निर्णय लेने की आवश्यकता है कि प्रत्येक भाषा संरचना प्रत्येक JSON संरचना के लिए सबसे अच्छी फिट है।

तो JSON निम्नलिखित संरचनाओं है ...

{} // object 
[] // array 

आप ध्यान रखें कि हालांकि बहुत JavaScript वस्तुओं और सरणियों के समान लग रहे हैं, वे नहीं सख्ती से ही कर रहे हैं।

संरचनाओं को JSON संरचनाओं के निर्माण के लिए उपयोग की जाने वाली संरचनाओं को JSON संरचनाओं की अनुमति देने के अनुरूप होना चाहिए। यही कारण है कि गैर-संख्यात्मक गुण को हटा दिया गया है।

जबकि JavaScript उन्हें कोई फर्क नहीं पड़ता, JSON उन्हें बर्दाश्त नहीं करेगा।

+0

गैर-संख्यात्मक गुण (बेहतर: गैर-संख्यात्मक * नाम * वाले गुण हटाए गए नहीं हैं)।उन्हें पहले स्थान पर पुनरावृत्ति के लिए नहीं माना जाता है। – PointedEars

+0

@PointedEars: वह खराब शब्द था। मेरा मतलब डेवलपर के परिप्रेक्ष्य के मामले के रूप में हटा दिया गया था, जैसा कि * "अरे, वे मेरे ऐरे ऑब्जेक्ट में हैं, लेकिन मेरे JSON टेक्स्ट में नहीं!" *। मुझे * "बहिष्कृत" * कहा जाना चाहिए था। –

-1

आपका कोड अर्थात् सही नहीं है, लेकिन क्योंकि अधिकांश जावास्क्रिप्ट इंजन प्रोग्रामर पर वास्तव में अच्छे हैं क्योंकि वे गलतियों की इन प्रकारों को अनुमति देते हैं।

एक त्वरित परीक्षण का मामला:

var a = []; 
a.b = "c"; 
console.log(JSON.stringify(a));//yields [], and not {"b":"c"} as you might expect 

यह JSON.stringify में कुछ कठोरता जो अभी भी एक Array तरह a व्यवहार करता है की वजह से हो सकता है। मैं इसके बारे में ज्यादा चिंता नहीं करता। यह एक ऐसी स्थिति है जो आपके प्रोग्राम में नहीं होनी चाहिए क्योंकि यह एक त्रुटि है। JSLint इन्हें पकड़ने और आपके कोड में कई और अधिक संभावित समस्याओं को पकड़ने के लिए एक लोकप्रिय उपकरण है।

+0

प्रार्थना करें, * वाक्यविन्यास * के साथ क्या गलत है? – PointedEars

+0

मैंने सोचा कि यह स्पष्ट था: आप 'ऐरे' में स्ट्रिंग कुंजियों की घोषणा नहीं कर सकते। सिर्फ इसलिए कि अधिकांश जावास्क्रिप्ट इंजन स्वीकार करते हैं, यह इसे _correct_ नहीं बनाता है। मुझे आशा है कि आपको लगता है कि डाउन-वोट इसके लायक था। – Halcyon

+0

ईसीएमएस्क्रिप्ट ऑब्जेक्ट्स की जावास्क्रिप्ट की प्रकृति, और प्रोग्रामिंग भाषा के सिंटैक्स से संबंधित गंभीर गलत धारणाएं हैं। इसके लिए एक टिप्पणी कम है। * कोई चाबियाँ नहीं हैं। * वस्तुओं के नाम * गुण * हैं। संपत्ति के नाम * तार * हैं, जो '[' ... ']', '.', या स्पष्ट रूप से (स्कोप श्रृंखला) के साथ उपयोग किए जाते हैं। जावास्क्रिप्ट एक ईसीएमएस्क्रिप्ट कार्यान्वयन है। * जावास्क्रिप्ट * में केवल दो उत्पादन-गुणवत्ता "कार्यान्वयन" हैं: स्पाइडरमोन्की और राइनो; जेस्क्रिप्ट जैसे अन्य * ईसीएमएस्क्रिप्ट * कार्यान्वयन हैं। जारी रखने के लिए ... – PointedEars

0

जावास्क्रिप्ट में, सब कुछ एक वस्तु है, इसलिए Arrays भी।

>> var l = [1, 2]; 
>> typeof l 
"object" 

Arrays वस्तुओं के रूप में एक ही तरह से जमा हो जाती है: इसी कारण आपको प्राप्त है। तो, वास्तव में, सरणी केवल हैशटेबल ऑब्जेक्ट्स हैं। इंडेक्स एक्सेस करते समय आप जो इंडेक्स प्रदान करते हैं

>> l[0] 

को ऑफसेट के रूप में व्याख्या नहीं किया गया है, लेकिन इसे धोया गया है और फिर खोजा गया है।

तो Arrays, केवल ऑब्जेक्ट्स (कुछ बिल्टिन सरणी-विधियों के साथ) हैं और इसलिए आप उन्हें ऑब्जेक्ट्स की तरह व्यवहार कर सकते हैं और एक निश्चित कुंजी के नीचे एक मान डाल सकते हैं। लेकिन संख्याओं द्वारा अनुक्रमित केवल उन चाबियों का उपयोग लंबाई की गणना करने के लिए किया जाता है।

>> var l = [] 
>> l.length 
0 
>> l[5] = 1; 
>> l.length 
6 
>> l 
[undefined, undefined, undefined, undefined, undefined, 1] 
>> l.hello = "Hello" 
>> l.length 
6 

अधिक जानकारी और Associative Arrays considered harmful आपने ऐसा क्यों नहीं करना चाहिए के लिए पढ़ें Array - MDN

+0

नहीं * सब कुछ * एक वस्तु है। आदिम मूल्य हैं। लेकिन कोई "जावास्क्रिप्ट" नहीं है, कई अलग-अलग ईसीएमएस्क्रिप्ट कार्यान्वयन हैं। – PointedEars

1

Array उदाहरणों और अन्य वस्तुओं के बीच अंतर ECMAScript Language Specification, Edition 5.1, खंड 15.4 में निर्दिष्ट हैं।

आप पाएंगे कि आप सभी वस्तु संदर्भ के साथ ब्रैकेट संपत्ति एक्सेसर सिंटैक्स का उपयोग कर सकते हैं, जबकि -

objRef[propertyName] 

- Array उदाहरणों विशेष कर रहे हैं। केवल एक पैरामीटर मान का उपयोग करना जो स्ट्रिंग प्रस्तुति का उपयोग करता है, 2 -1 से कम एक हस्ताक्षरित 32-बिट पूर्णांक मान का है, encapsulated सरणी संरचना का एक तत्व एक्सेस करता है, और पहुंच लिखने Array इंस्टेंस की length संपत्ति के मान को प्रभावित करती है।

धारा 15.12 JSON ऑब्जेक्ट और इसके अनुसार stringify विधि निर्दिष्ट करता है।

संबंधित मुद्दे