2012-05-02 13 views
8

मुझे कुछ ऑब्जेक्ट्स वाले जावास्क्रिप्ट सरणी के साथ एक अजीब व्यवहार का सामना करना पड़ रहा है (शायद यह बिल्कुल अजीब नहीं है बल्कि मुझे समझ में नहीं आता है)।जावास्क्रिप्ट सरणी एक ऑब्जेक्ट स्ट्रक्चर बन जाती है

चूंकि मैं कोई जावास्क्रिप्ट समर्थक नहीं हूं, इसलिए यह स्पष्ट रूप से स्पष्ट हो सकता है कि यह क्यों हो रहा है, मुझे बस यह नहीं पता।

मेरे पास एक दस्तावेज़ में चल रहा जावास्क्रिप्ट है। यह इस के समान वस्तुओं की एक सरणी बनाता है:

var myArray = [{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...]; 

अगर मैं जगह यह JSON.stringify (myArray) की तरह बनाया गया था पर इस सरणी प्रिंट आउट, मैं मैं क्या उम्मीद कर रहा था मिलती है:

[{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...] 

हालांकि, अगर मैं इस दस्तावेज़ को इस दस्तावेज़ में किसी दस्तावेज़ दस्तावेज़ से एक्सेस करने का प्रयास करता हूं (पहले दस्तावेज़ द्वारा खोली गई विंडो में एक दस्तावेज़) सरणी अब कोई सरणी नहीं है। तो बच्चे को दस्तावेज़ में JSON.stringify (parent.opener.myArray) कर निम्नलिखित में परिणाम होगा:

{"0":{"Id":"guid1","Name":"name1"},"1":{"Id":"guid2","Name":"name2"},...} 

और यह मैं क्या नहीं उम्मीद कर रहा था था - मैं एक ही प्राप्त करने के लिए उम्मीद कर रहा था के रूप में मैं में किया था तेह मूल दस्तावेज।

क्या कोई मुझे बता सकता है कि यह क्यों हो रहा है और इसे कैसे ठीक किया जाए ताकि सरणी अभी भी एक सरणी है जब बच्चे की खिड़की/दस्तावेज़ से संबोधित किया जाता है?

पी एस। वस्तुओं सरणी के रूप में ऊपर कहा गया है, वे इस तरह जुड़ जाते हैं आप नहीं जोड़े जाते:

function objTemp() 
{ 
    this.Id = ''; 
    this.Name = ''; 
}; 

var myArray = []; 

var obj = new ObjTemp(); 
obj.Id = 'guid1'; 
obj.Name = 'name1'; 

myArray[myArray.length] = obj; 

है कि किसी भी फर्क नहीं पड़ता है।

किसी भी मदद की बहुत सराहना किया जाएगा, दोनों मेरी समस्या ठीक करने के लिए, लेकिन यह भी बेहतर समझ है कि समस्या क्या कारण हो सकता है :)

+0

मैं पुन: पेश नहीं कर सकता। आपने किस ब्राउजर में परीक्षण किया था? क्या आपने JSON लाइब्रेरी का उपयोग किया था? – Bergi

+0

मैं आईई में परीक्षण कर रहा हूं क्योंकि यह एक आवश्यकता है। व्यक्तिगत रूप से मैं आईई नहीं चुनूंगा लेकिन यह मेरे ऊपर नहीं है। मैं केवल अपनी चेतावनी को मजबूत करने के लिए इस उदाहरण में जेसन का उपयोग कर रहा हूं। मैं उस कोड के लिए किसी भी जेसन लाइब्रेरी का उपयोग नहीं कर रहा हूं जो व्यवहार उत्पन्न करता है। – Aidal

+0

हाय, स्वीकार करने के लिए धन्यवाद। मेरे कामकाज को जानने में खुशी हुई साबित हुई। आपके प्रश्न बीटीडब्ल्यू के लिए हैप्पी कोडिंग :) + 1। मैंने उससे सीखा, –

उत्तर

6

आखिरी लाइन पर जा रहा है के लिए, आप myArray.push(obj); साथ myArray[myArray.length] = obj; की जगह की कोशिश की? ऐसा हो सकता है, चूंकि आप स्पष्ट रूप से एक नई अनुक्रमणिका बना रहे हैं, इसलिए ऐरे को ऑब्जेक्ट में बदल दिया गया है ... हालांकि मैं यहां अनुमान लगा रहा हूं। क्या आप बच्चे दस्तावेज़ द्वारा उपयोग किए गए कोड को जोड़ सकते हैं जो myArray पुनर्प्राप्त करता है?

संपादित

, ऊपर ध्यान न दें, क्योंकि यह कोई फर्क नहीं होगा। हालांकि, घमंड करने के बिना, मैं सही लाइनों के साथ सोच रहा था। मेरा विचार था कि, केवल स्वामित्व सरणी विधियों का उपयोग करके, दुभाषिया यह देखेगा कि myArray के प्रकार के रूप में सुराग के रूप में। बात यह है: myArray एक सरणी है, जहाँ तक मूल दस्तावेज़ का संबंध है, लेकिन जब से आप एक दस्तावेज़ से सरणी गुजर रहे हैं, यहाँ क्या होता है:

एक सरणी एक वस्तु है, के साथ पूरा यह अपने प्रोटोटाइप और तरीकों का है। इसे किसी अन्य दस्तावेज़ में पास करके, आप पूरे ऑरे ऑब्जेक्ट (मान और प्रोटोटाइप) को बच्चे दस्तावेज़ में एक ऑब्जेक्ट के रूप में पास कर रहे हैं। दस्तावेज़ों के बीच चर पारित करने में, आप प्रभावी रूप से चर की एक प्रति बना रहे हैं (केवल एक बार जावास्क्रिप्ट एक var के मानों की प्रतिलिपि बनाता है)। चूंकि एक सरणी एक वस्तु है, इसकी सभी गुण (और प्रोटोटाइप विधियों/गुणों) को Object ऑब्जेक्ट के 'नामहीन' उदाहरण में कॉपी किया गया है। var copy = new Object(toCopy.constructor(toCopy.valueOf())); की लाइनों के साथ कुछ हो रहा है ...इस के आसपास सबसे आसान तरीका है, IMO, सरणी माता पिता संदर्भ के भीतर तंगी के लिए, क्योंकि, दुभाषिया जानता है कि यह एक सरणी है:

//parent document 
function getTheArray(){ return JSON.stringify(myArray);} 
//child document: 
myArray = JSON.parse(parent.getTheArray()); 

इस उदाहरण में, वर संदर्भ है कि अभी भी myArray व्यवहार करता है में stringified है एक वास्तविक जावास्क्रिप्ट सरणी के रूप में, इसलिए परिणामी स्ट्रिंग वह होगी जो आप उम्मीद करेंगे। एक दस्तावेज़ से दूसरे दस्तावेज़ में JSON एन्कोडेड स्ट्रिंग को पार करने में, यह अपरिवर्तित रहेगा और इसलिए JSON.parse() आपको myArray चर की एक सटीक प्रतिलिपि देगा।

ध्यान दें कि यह अंधेरे में सिर्फ एक और जंगली स्टैब है, लेकिन मैंने इसे थोड़ा और विचार दिया है। अगर मैं इसके बारे में गलत हूं, तो मुझे सही करने के लिए स्वतंत्र महसूस करें ... मुझे हमेशा सीखने में खुशी होती है। यदि यह सच साबित हो जाता है, तो मुझे भी बताएं, क्योंकि यह निस्संदेह मेरे लिए एक पतन साबित होगा या बाद में

+0

नहीं, यह वाक्यविन्यास एक ऐरे का नया सदस्य बनाने के लिए पूरी तरह से मान्य है। हालांकि .push() अधिक वर्णनात्मक है (और मुझे यह बेहतर पसंद है), असाइनमेंट भी काम करता है और थोड़ा तेज़ भी है। – Bergi

+0

मुझे नहीं लगता कि सरणी अमान्य है जिस तरह से मैं इसमें आइटम जोड़ता हूं, जैसा कि मैंने पोस्ट में भी कहा है, अगर मैं स्ट्रिंग को सरणीकृत करने की कोशिश करता हूं तो यह सही दिखता है (उर्फ यह ऑब्जेक्ट नहीं बल्कि एक सरणी है) । यदि मैं बच्चे दस्तावेज़ से सटीक वही काम करता हूं तो सरणी अब एक वस्तु है, न केवल अगर मैं var stringified को सतर्क करता हूं लेकिन सरणी के साथ काम करने वाला कोड त्रुटि उत्पन्न करता है क्योंकि उदा। myArray [0] आईडी शून्य है (क्योंकि यह कारण नहीं है)। – Aidal

+0

अभिभावक पृष्ठ पर सरणी को स्ट्रिंग करना और उसके बाद बच्चे पृष्ठ पर स्ट्रिंग को पार्स करना चाल था, और इसके बजाय पूरी तरह से उत्तर देने के लिए धन्यवाद, मैंने कुछ भी सीखा :) – Aidal

1

इस व्यवहार और स्पष्टीकरण के उदाहरण के लिए इस आलेख http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/ के अंत की जांच करें।

असल में यह ऐरे को मूल प्रकार के रूप में आता है और प्रत्येक फ्रेम में अपने मूल निवासी और चर के सेट होते हैं।

// in parent window 
var a = []; 
var b = {}; 
//inside the iframe 
console.log(parent.window.a); // returns array 
console.log(parent.window.b); // returns object 

alert(parent.window.a instanceof Array); // false 
alert(parent.window.b instanceof Object); // false 
alert(parent.window.a.constructor === Array); // false 
alert(parent.window.b.constructor === Object); // false 

JSON.stringify को आपका कॉल वास्तव में निम्नलिखित जांच (json.js स्रोत से) निष्पादित करता है, जो किसी सरणी के रूप में यह निर्दिष्ट करने के लिए असफल रहने के किया जा रहा है:

लेख से

 // Is the value an array? 
     if (Object.prototype.toString.apply(value) === '[object Array]') { 
      //stringify 
+1

ना, ऐसा लगता है कि वास्तव में Array.isArray का उपयोग नहीं करना है, जो क्रॉस-विंडो काम करेगा, इसके बजाय यह वर्णित व्यवहार का कारण बनने के लिए उदाहरण का उपयोग करेगा। – Bergi

+0

ओह हाँ ऐसा लगता है कि यह अब ब्राउज़र विशिष्ट है क्योंकि json2.js डिफ़ॉल्ट रूप से ब्राउज़र के मूल संस्करण को निष्पादित करने के लिए डिफ़ॉल्ट रूप से निष्पादित करने के लिए डिफ़ॉल्ट है (और यह सभी आधुनिक ब्राउज़रों में होना चाहिए) – nvuono

+0

मेरा मतलब है 'Object.prototype.toString .apply (value) === '[ऑब्जेक्ट ऐरे]' 'ऐसा नहीं होगा * विफल होगा, आप ऐसा कहने के बावजूद। – Bergi

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