11

我遇到了一个奇怪的行为(也许它根本不奇怪,但只是我不明白为什么)一个包含一些对象的 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"},...}

这不是我所期望的——我期望得到与我在父文档中所做的一样的结果。

谁能向我解释为什么会发生这种情况以及如何解决它,以便从子窗口/文档寻址时数组仍然是数组?

PS。对象不会如上所述添加到数组中,它们是这样添加的:

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

var myArray = [];

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

myArray[myArray.length] = obj;

如果这有什么不同的话。

任何帮助都将不胜感激,既可以解决我的问题,也可以更好地了解正在发生的事情:)

4

2 回答 2

7

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

编辑

忽略上面的,因为它不会有任何区别。不过,不想吹嘘,我的想法是正确的。我的想法是,通过仅使用专有数组方法,解释器会将其视为myArray. 问题是:就父文档而言,它myArray 一个数组,但是由于您将数组从一个文档传递到另一个文档,因此会发生以下情况:

数组是一个对象,具有自己的原型和方法。通过将它传递给另一个文档,您将整个 Array 对象(值和原型)作为一个对象传递给子文档。在文档之间传递变量时,您实际上是在创建变量的副本(JavaScript 唯一一次复制 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());

在此示例中,var 在仍被视为myArray真正的 JavaScript 数组的上下文中被字符串化,因此生成的字符串将是您所期望的。在将 JSON 编码字符串从一个文档传递到另一个文档时,它将保持不变,因此JSON.parse()将为您提供myArray变量的精确副本。

请注意,这只是黑暗中的又一次野刺,但现在我已经考虑了更多。如果我对此有误,请随时纠正我......我总是很高兴学习。如果这是真的,也请告诉我,因为这无疑迟早会成为我的陷阱

于 2012-05-02T09:17:42.003 回答
1

查看本文结尾http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/以获取此行为和解释的示例。

基本上它归结为 Array 是一种本机类型,并且每个帧都有自己的一组本机和变量。

来自文章:

// 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
于 2012-05-02T09:24:07.897 回答