Javascript array becomes an object structure

I experience strange behavior (maybe this is not strange, but I just don’t understand why) with a javascript array containing some objects.

Since I am not a javascript developer, there may well be a clear explanation of why this is happening, I just don't know this.

I have javascript that works in a document. It makes an array of objects look like this:

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

If I print this array in the place where it was created as JSON.stringify (myArray), I get what I expected:

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

However, if I try to access this array from a child document into this document (the document in the window opened by the first document), the array is no longer an array. Thus, executing JSON.stringify (parent.opener.myArray) in the child document will result in the following:

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

And this was not what I expected - I expected to get the same as in the parent document.

Can someone explain to me why this is happening and how to fix it so that the array is still an array when accessed from a child window / document?

PS. objects are not added to the array, as indicated above, they are added as follows:

 function objTemp() { this.Id = ''; this.Name = ''; }; var myArray = []; var obj = new ObjTemp(); obj.Id = 'guid1'; obj.Name = 'name1'; myArray[myArray.length] = obj; 

If that matters.

Any help would be greatly appreciated both for fixing my problem and for a better understanding of what is happening :)

+8
javascript object arrays
source share
2 answers

The very last line may cause a problem if you tried to replace myArray[myArray.length] = obj; on myArray.push(obj); ? Maybe since you are creating a new index explicitly, the array turns into an object ... although I am just guessing here. Could you add the code used by the child document that retrieves myArray ?

Edit

Ignore the above, as this will not make any difference. Although, not wanting to boast, I thought in the right line. My idea was that using only the native methods of the array, the interpreter would see this as hints regarding the type myArray . The fact is that myArray is an array with respect to the parent document, but since you are passing an array from one document to another, this is what happens:

An array is an object that has its own prototype and methods. Passing it to another document, you pass the entire Array object (value and prototype) as one object for the child document. By passing a variable between documents, you actually create a copy of the variable (the only time JavaScript copies var values). Since the array is an object, all its properties (and methods / properties of the prototype) are copied to the "nameless" instance of the Object . Something in the lines var copy = new Object(toCopy.constructor(toCopy.valueOf())); happens ... the easiest way to do this is IMO, is the strictness of the array with the parent context, because there the interpreter knows it as an array:

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

In this example, var is gated in a context that still considers myArray be a true JavaScript array, so the resulting string will be what you expect. Passing the encoded JSON string from one document to another, it will remain unchanged, and therefore JSON.parse() will provide you with an exact copy of the myArray variable.

Note that this is just another wild hit in the dark, but now I thought a little. If I am wrong about this, do not hesitate to correct me ... I am always happy to find out. If this turns out to be true, let me know, as it will undoubtedly sooner or later be a trap for me.

+6
source share

Check out the end of this article http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/ for an example of this behavior and explanation.

Basically it comes down to the fact that the array is native, and each frame has its own set of natives and variables.

From the article:

 // 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 

Your JSON.stringify call does the following check (from the json.js source), which does not seem to indicate it as an array:

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

All Articles