2012-10-29 7 views
9

यहां क्या हो रहा है?जावास्क्रिप्ट में ऑब्जेक्ट (और इसके विपरीत) द्वारा सरणी बनाना?

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}} 

यह वास्तव में एक सरणी बनाता है:

["foo", "bar", "f"] 

कहाँ इस संरचना सिंटैक्स के लिए दस्तावेज़ है?

यह भी स्मार्ट है:

के लिए बदल रहा: (नोटिस 0, 1, 3)

var x = {length:3, '0':'foo', '1':'bar','3':'f', splice:function(){}} 

इच्छा गंदगी सरणी और यह हो जाएगा:

["foo", "bar", undefined × 1] 

इसके अलावा, को हटाने स्प्लिस फ़ंक्शन:

var x = {length:3, '0':'foo', '1':'bar','2':'f'} 

पैदावार: (नियमित वस्तु)

Object 
0: "foo" 
1: "bar" 
2: "f" 
length: 3 
__proto__: Object 

तो मैं दो प्रश्न हैं:

  • इस संरचना क्या है? length , element , splice

  • मैं ['john','paul','yoko'] है कहो और अब मैं वस्तु

    var x = {length:3, '0':'john', '1':'paul','2':'yoko', splice:function(){}}

    मैं यह कर होगा कैसे बनाना चाहते हैं?

+0

* यह वास्तव में एक सरणी बनाता है *, क्यों? क्योंकि कंसोल इसे एक सरणी के रूप में दिखाता है? शायद कुछ अनुकूलित परीक्षण। 'x.constructor' 'कार्य ऑब्जेक्ट() ...' देता है। – Yoshi

+0

योशी आपको एक बिंदु मिला: 'Object.prototype.toString.apply (x)' = '" ऑब्जेक्ट ऑब्जेक्ट] "' –

उत्तर

6

एक सरणी जब आप console.log(x) बनाने के कुछ तरीकों के साथ लागू किया, एक वस्तु से और कुछ नहीं है, अपने कंसोल एक सरणी के मॉडल को पहचानता है, और यह प्रदर्शित किया है जैसा कि ऐसा करना कॉन्फ़िगर किया गया है।

Arrayजावास्क्रिप्ट में एक वस्तु डिफ़ॉल्ट रूप से उपलब्ध है, और यह ब्राउज़र द्वारा अन्य वस्तुओं (@MathiasSchwarz टिप्पणी देखें) की तुलना में अलग थोड़ा नियंत्रित किया जाता है, लेकिन इसकी संरचना में, यह दूसरों की तरह एक वस्तु है (वहाँ वे विधियां जिन्हें आप कॉल कर सकते हैं, और आप इंडेक्स जोड़ सकते हैं। हालांकि, आप आमतौर पर "सामान्य" ऑब्जेक्ट्स जैसे स्ट्रिंग इंडेक्स का उपयोग नहीं करते हैं, क्योंकि इसका उद्देश्य इस तरह इस्तेमाल नहीं करना है)।

लेकिन आपकी ऑब्जेक्ट वास्तव में Array नहीं है, तो आप जो कुछ भी चाहते हैं उसे कंसोल में प्रदर्शित किए जाने के संदर्भ में कर सकते हैं।

+0

स्प्लिस func क्यों है? –

+1

यह पूरी तरह से सही नहीं है। Arrays एक विशेष प्रकार की वस्तुओं हैं। प्रिंटिंग व्यवहार केवल इस तथ्य के कारण होता है कि एक सरणी में 'toString' विधि होती है। इस तरह की एक विधि को प्रोग्रामर द्वारा आसानी से कार्यान्वित किया जा सकता है। सरणी के बारे में विशेष बात 'लंबाई' फ़ील्ड है जिसे सरणी अद्यतन होने पर स्वचालित रूप से अपडेट किया जाता है। ऐसे क्षेत्र को प्रोग्रामर द्वारा कार्यान्वित नहीं किया जा सकता है, इसलिए यह वास्तव में किसी ऑब्जेक्ट से अधिक है ... –

+1

@ रॉयनामिर: ऐसा लगता है क्योंकि कंसोल इसे 'लम्बाई' और 'स्प्लिस' फ़ील्ड में देखकर सरणी के रूप में पहचानता है (IMO)। – SuperSaiyan

3

x एक सरणी नहीं है, यह केवल एक वस्तु है। (सांत्वना सरणी प्रारूप में यह पता चलता है, कि कंसोल के कार्यान्वयन की समस्या है।)

var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}}; 
console.log(typeof x); // object 

बस, उदाहरण के रूप में फ़ायरबग का उपयोग फ़ायरबग के स्रोत कोड पर एक नज़र डालें, और तुम क्यों देखेंगे कंसोल ने इसे एक सरणी के रूप में सोचा।

//... 
isArray: function(obj, win) 
{ 
    if (mightBeArray(obj, win)) 
    { 
     if (!obj) 
      return false; 
     // do this first to avoid security 1000 errors 
     else if (obj instanceof Ci.nsIDOMHistory) 
      return false; 
     // do this first to avoid exceptions 
     else if (obj.toString && obj.toString() === "[xpconnect wrapped native prototype]") 
      return false; 
     else if (isFinite(obj.length) && typeof obj.splice === "function") 
      return true; 
     else if (Arr.isArray(obj)) 
      return true; 
    } 

    return false; 
}, 
// ... 
+0

ऑब्जेक्ट.प्रोटोटाइप.toString.apply (x) "[ऑब्जेक्ट ऑब्जेक्ट]" बेहतर है IMHO –

2
var x = {length:3, '0':'foo', '1':'bar','2':'f', splice:function(){}} 

एक सरणी की तरह दिखता है, लेकिन नहीं है। यदि आप x.forEach(function(e){...}) आज़माते हैं तो यह विफल हो जाता है लेकिन यदि आप [1,2,3].forEach(function(e){...}) करते हैं।

आप शाब्दिक ऑब्जेक्ट नोटेशन के माध्यम से एक वास्तविक सरणी का निर्माण करना चाहते हैं, तो आप कर सकता है

var x = {length:3, ... , __proto__:Array.prototype} 

ध्यान दें, तथापि, एक वस्तु इस की तरह बनाया अभी भी यह अपडेट नहीं होगा पर length संपत्ति है लिखना।

ऑब्जेक्ट्स जिनमें लम्बाई और न्यूमेरिक इंडेक्स होता है उन्हें छद्म-सरणी जावास्क्रिप्ट कहा जाता है। इनमें से एक उदाहरण jQuery वस्तु है।

क्रोम कंसोलप्रदर्शित करता है एक length और splice सरणियों के रूप में लेकिन उस के साथ वस्तुओं मतलब यह नहीं है कि वे सरणियों कर रहे हैं।

0

निर्मित ऑब्जेक्ट एक सरणी नहीं है, लेकिन यह एक (अपरिवर्तनीय हालांकि) के रूप में व्यवहार करेगा क्योंकि इसमें लंबाई क्षेत्र और splice विधि है।

एक जावास्क्रिप्ट ऐरे में length फ़ील्ड स्वचालित रूप से अपडेट होने पर फ़ील्ड स्वचालित रूप से अपडेट हो जाती है। यह आपके ऑब्जेक्ट का मामला नहीं होगा। आपकी ऑब्जेक्ट में, length फ़ील्ड बनी रहेगी इससे कोई फर्क नहीं पड़ता कि ऑब्जेक्ट में क्या है। यही कारण है कि जब आप इंडेक्स को 0,1,3 में बदलते हैं तो चीजें अब काम नहीं करतीं। इस मामले में लंबाई क्षेत्र के बजाय 4 होना चाहिए था। चूंकि मान है, तो पुनरावृत्ति इंडेक्स 2 के बाद रुक जाएगी जो वास्तव में अपरिभाषित है क्योंकि आपने इंडेक्स 2 के लिए कोई मान निर्धारित नहीं किया है ...

+0

क्या आपको विश्वास है कि परिणामस्वरूप सरणी अपरिवर्तनीय है? –

+0

ठीक है, यह किसी ऑब्जेक्ट के रूप में अपरिवर्तनीय नहीं है, लेकिन 'splice' फ़ंक्शन कुछ भी नहीं करेगा और ऐरे के लिए उत्परिवर्तन कार्यों में से कोई भी उपलब्ध नहीं है। मेरा मतलब वही था... –

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