2013-04-11 11 views
12

मैं अत्यधिक संसाधन-बाधित एम्बेडेड डिवाइस (http://www.espruino.com) के लिए एक जावास्क्रिप्ट दुभाषिया लिख ​​रहा हूं, और हर बार जब मुझे लगता है कि मैंने कुछ जावास्क्रिप्ट सही तरीके से कार्यान्वित किया है, तो मुझे एहसास है कि मैं गलत हूं।जावास्क्रिप्ट [] वास्तव में कैसे काम करता है?

मेरा प्रश्न अब [] है। आप जावास्क्रिप्ट के सबसे बुनियादी बिट्स में से एक को सही ढंग से कैसे कार्यान्वित करेंगे?

मैंने जावास्क्रिप्ट स्पेक को देखा है और शायद मुझे सही नहीं मिला है, लेकिन मुझे एक उपयोगी उत्तर नहीं मिल रहा है।

मैंने पहले माना था कि आपके पास प्रभावी रूप से दो 'मानचित्र' थे - एक पूर्णांक के लिए, और तारों के लिए एक। और सरणी लंबाई उच्चतम पूर्णांक प्लस वन का मान था। हालांकि यह गलत लगता है, क्रोम पर jsconsole के अनुसार:

var a = []; 
a[5] = 42; 
a["5"]; // 42 
a.length; // 6 

लेकिन यह भी:

var a = []; 
a["5"] = 42; 
a[5]; // 42 
a.length; // 6 

तो ... महान - सब कुछ एक स्ट्रिंग में, बदल जाती है और उच्चतम मूल्य का स्ट्रिंग कि एक पूर्णांक का प्रतिनिधित्व करता है लंबाई प्राप्त करने के लिए (प्लस वन) का उपयोग किया जाता है? गलत।

var a = []; 
a["05"] = 42; 
a.length; // 0 

"05" एक वैध पूर्णांक है - यहां तक ​​कि ऑक्टल में भी। तो यह लंबाई को प्रभावित क्यों नहीं करता है?

क्या आपको स्ट्रिंग को एक पूर्णांक में परिवर्तित करना है, और तब जांचें कि स्ट्रिंग में वापस परिवर्तित होने पर, यह मेल खाता है?

क्या किसी के पास किसी एरे या ऑब्जेक्ट में आइटम स्टोर करने और प्राप्त करने के लिए उपयोग किए जाने वाले सटीक एल्गोरिदम का संदर्भ है? ऐसा लगता है कि यह बहुत आसान होना चाहिए, लेकिन ऐसा लगता है कि वास्तव में यह नहीं है!

+6

[मानक] (http://www.ecma-international.org/ecma-262/5.1/#sec-15.4) कहता है: "* एक संपत्ति का नाम' पी' ('स्ट्रिंग 'के रूप में मान) एक सरणी अनुक्रमणिका है यदि केवल तभी 'ToString (ToUint32 (P)) '' 'के बराबर है और' ToUint32 (P) '' ** ** 32-1' के बराबर नहीं है। * "। – DCoder

+6

यदि आप एक दुभाषिया लिख ​​रहे हैं, तो धारणाओं का उपयोग नहीं किया जाना चाहिए। आपको कल्पना पढ़ना चाहिए। –

+0

आप वी 8 की तरह मौजूदा, शक्तिशाली और मानक-अनुरूप जेएस कार्यान्वयन का उपयोग क्यों नहीं करते? मैंने जो पढ़ा है http://www.espruino.com/Performance पर भयानक लग रहा था: -/ – Bergi

उत्तर

4

चश्मा के रूप में कहा, और दूसरों के द्वारा नोट किया गया था:

"एक प्रॉपर्टी का नाम पी (एक स्ट्रिंग मान के रूप में) एक सरणी सूचकांक है यदि और केवल यदि ToString (ToUint32 (पी)) पी और ToUint32 के बराबर है (पी) 2^32-1 के बराबर नहीं है। "

क्यों अपने परिदृश्य "5" में एक सरणी सूचकांक और "05" माना जाता है के समझाने कि नहीं है:

console.log("5" === String("5" >>> 0)); 
// true, "5" is equal to "5", so it's an index 

console.log("05" === String("05" >>> 0)); 
// false, "05" is not equal to "5", so it's not an index 

नोट: Zero-fill right shiftToUint32 का एक विकल्प है करने के लिए जे एस में सबसे छोटा रास्ता, एक नंबर स्थानांतरण है शून्य से

+0

धन्यवाद - यह सरणी लंबाई के साथ समस्या को भी समझाता है, जो अन्य उत्तरों वास्तव में संबोधित नहीं किया गया था। डीसीओडर के साथ-साथ spec के लिंक के लिए धन्यवाद –

3

Arrays केवल ऑब्जेक्ट्स हैं। इसका मतलब है कि उनके पास अतिरिक्त गुण हो सकते हैं जिन्हें सरणी के तत्व नहीं माना जाता है।

यदि वर्ग ब्रैकेट तर्क एक पूर्णांक है, तो यह सरणी को असाइनमेंट करने के लिए इसका उपयोग करता है। अन्यथा, यह इसे एक स्ट्रिंग के रूप में मानता है और इसे सरणी ऑब्जेक्ट पर एक संपत्ति के रूप में संग्रहीत करता है।

संपादित delnan की टिप्पणी और DCoder की टिप्पणी के आधार पर, यह कैसे जावास्क्रिप्ट निर्धारित करता है कि यह एक सरणी के लिए एक उपयुक्त सूचकांक है (बस एक संपत्ति की तुलना में) है: http://www.ecma-international.org/ecma-262/5.1/#sec-15.4

+0

अंतिम भाग विशेष रूप से उपयोगी नहीं है जब तक आप परिभाषित नहीं करते * वास्तव में * "एक पूर्णांक" क्या है और क्या नहीं है।उदाहरण के लिए, एक पूर्णांक "05" है और क्यों (नहीं)? – delnan

4

देखें MDN

जावास्क्रिप्ट सरणी इंडेक्स को भी उद्धृत करना संभव है (उदाहरण के लिए, वर्षों [2]] वर्षों के बजाय [2]], हालांकि यह आवश्यक नहीं है। वर्षों में 2 [2] अंततः जावास्क्रिप्ट इंजन द्वारा एक स्ट्रिंग में घुमाया जाता है, वैसे भी, एक अंतर्निहित टूस्ट्रिंग रूपांतरण के माध्यम से। यह के लिए इस कारण यह है कि "2" और "02" पर दो अलग-अलग स्लॉट को उल्लेख करता है साल आपत्ति है और निम्न उदाहरण सच लॉग:

console.log(years["2"] != years["02"]); 
a["5"] साथ

तो तुम सरणी, जबकि एक्सेस कर रहे हैं a["05"] सरणी ऑब्जेक्ट पर एक संपत्ति सेट करता है।

1

Arrays भी ऑब्जेक्ट्स हैं।

इस

a["05"] = 5; 

कर आप के रूप में ही बात कर रहे द्वारा:

a.05 = 5; 

हालांकि, ऊपर एक सिंटैक्स त्रुटि में परिणाम होगा, के रूप में एक संपत्ति एक बिंदु के बाद निर्दिष्ट नहीं कर सकते एक संख्या से शुरू करें।

तो अगर आप ऐसा करते हैं:

a = []; 
a["05"] = 5; 

आप अभी भी एक खाली सरणी, लेकिन a की संपत्ति 05 नामक मूल्य 5 है।

संख्या xis an array index यदि और केवल यदि ToString(ToUint32(x))x के बराबर है (ताकि जाता है कि आवश्यकता को पूरा नहीं "05" के मामले में)।

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