Javascript数组成为对象结构

Javascript数组成为对象结构,javascript,arrays,object,Javascript,Arrays,Object,对于包含一些对象的javascript数组,我遇到了一种奇怪的行为(可能一点也不奇怪,只是我不明白为什么) 由于我不是javascript专业人士,可能会有很清楚的解释来解释为什么会发生这种情况,我只是不知道 我有一个运行在文档中的javascript。它使对象数组类似于以下内容: var myArray = [{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...]; 如果我在创建这个数组的地方像JSON.stringi

对于包含一些对象的javascript数组,我遇到了一种奇怪的行为(可能一点也不奇怪,只是我不明白为什么)

由于我不是javascript专业人士,可能会有很清楚的解释来解释为什么会发生这种情况,我只是不知道

我有一个运行在文档中的javascript。它使对象数组类似于以下内容:

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;
如果这有什么区别的话


任何帮助都将不胜感激,无论是为了解决我的问题,还是为了更好地理解正在发生的事情:)

最后一行可能会导致问题,您是否尝试过替换
myArray[myArray.length]=objmyArray.push(obj)进行编码?可能是这样的,因为您显式地创建了一个新索引,所以数组会变成一个对象。。。虽然我只是在猜。能否添加检索myArray的子文档使用的代码

编辑

忽略以上内容,因为这不会有任何区别。虽然我不想自夸,但我的想法是正确的。我的想法是,仅通过使用专有的数组方法,解释器就会将其视为关于
myArray
类型的线索。问题是:
myArray
对于父文档来说是一个数组,但是由于您将数组从一个文档传递到另一个文档,因此会发生以下情况:

数组是一个对象,包含它自己的原型和方法。通过将其传递给另一个文档,您将整个数组对象(值和原型)作为一个对象传递给子文档。在文档之间传递变量时,实际上是在创建变量的副本(JavaScript复制变量值的唯一时间)。因为数组是一个对象,所以它的所有属性(以及原型方法/属性)都被复制到
对象的“无名”实例中。类似于
var copy=newobject(toCopy.constructor(toCopy.valueOf())正在发生。。。IMO,最简单的解决方法是使用父上下文严格限制数组,因为在父上下文中,解释器知道它是一个数组:

//parent document
function getTheArray(){ return JSON.stringify(myArray);}
//child document:
myArray = JSON.parse(parent.getTheArray());
在本例中,var在仍然将
myArray
视为真正的JavaScript数组的上下文中进行了字符串化,因此生成的字符串将是您所期望的。在将JSON编码的字符串从一个文档传递到另一个文档时,它将保持不变,因此
JSON.parse()
将为您提供
myArray
变量的精确副本


请注意,这只是黑暗中的又一次疯狂尝试,但我现在已经对它进行了更多的思考。如果我错了,请随时纠正我。。。我总是很高兴学习。如果这是真的,也请让我知道,因为这无疑会成为我迟早会遇到的一个陷阱

请查看本文末尾,以获取有关这种行为和解释的示例

基本上,它归结为数组是本机类型,每个帧都有自己的本机和变量集

从文章中:

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

不,该语法对于创建数组的新成员完全有效。虽然.push()更具描述性(我更喜欢它),但赋值也有效,甚至更快。我不认为数组无效,因为我向数组中添加项目的方式,正如我在文章中所述,如果我尝试警告字符串化的数组,它看起来是正确的(即它不是对象,而是数组)。如果我在子文档中执行完全相同的操作,那么数组现在就是一个对象,不仅是在我警告变量stringified时,而且应该使用该数组的代码会抛出一个错误,因为例如myArray[0]。Id为null(因为它不存在)。将父页面上的数组串起来,然后在子页面上解析字符串就成功了。多亏了这个相当彻底的答案,我也学到了一些东西:)在我的例子中,用
[I]=x
替换
.push(x)
实际上以某种方式保留了
.slice
方法。然而使用stringify给了我一个奇怪的
意外标记a
:1当在另一个窗口中将给定数组分配给新对象时,IE 11中仍然存在这个问题。不,似乎完全没有使用array.isArray,它可以跨窗口工作,相反,它将使用instanceof来引起所描述的行为。哦,是的,这看起来是特定于浏览器的,因为json2.js默认为只执行浏览器的原生版本的stringify(如果有可用的话)(在所有现代浏览器中都应该是这样),我指的是代码
Object.prototype.toString.apply(value)=='[对象数组]“
不会失败,尽管你这么说。你在哪个浏览器上测试?我记得有一个线程,在IE中发生了完全相同的行为,但在FF中没有。您能提供一个JSFIDLE来测试这个问题吗?看,我无法复制。您在哪个浏览器中进行了测试?你使用JSON库了吗?我在IE中测试,因为这是一个需求。也许我不会选,但这不取决于我