我正在经历一个奇怪的行为(也许它根本不奇怪但只是我不理解为什么)使用包含一些对象的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;
如果这有任何区别。
任何帮助都会非常感激,无论是为了解决我的问题,还是为了更好地了解正在发生的事情:)
答案 0 :(得分:6)
最后一行可能会导致此问题,您是否尝试将myArray[myArray.length] = obj;
替换为myArray.push(obj);
?可能是这样,因为你明确地创建了一个新索引,所以Array变成了一个对象......虽然我只是在这里猜测。您可以添加检索myArray
的子文档使用的代码吗?
修改强>
忽略上述内容,因为它不会有任何区别。虽然,我不想夸耀,但我正在思考正确的思路。我的想法是,通过仅使用专有数组方法,解释器会将其视为myArray
类型的线索。问题是:myArray
是一个数组,就父文档而言,但是因为你将数组从一个文档传递到另一个文档,所以会发生以下情况:
数组是一个对象,包含它自己的原型和方法。通过将其传递给另一个文档,您将整个Array对象(值和原型)作为一个对象传递给子文档。在文档之间传递变量时,您可以有效地创建变量的副本(JavaScript复制var值的唯一时间)。由于数组是一个对象,因此将其所有属性(和原型方法/属性)复制到Object
对象的“无名”实例。正在发生var copy = new Object(toCopy.constructor(toCopy.valueOf()));
的某些事情......最简单的方法就是使用父上下文严格控制数组,因为在那里,解释器知道它是一个数组:
//parent document
function getTheArray(){ return JSON.stringify(myArray);}
//child document:
myArray = JSON.parse(parent.getTheArray());
在这个例子中,var在仍然将myArray
视为真正的JavaScript数组的上下文中进行了字符串化,因此生成的字符串将是您所期望的。在将JSON编码的字符串从一个文档传递到另一个文档时,它将保持不变,因此JSON.parse()
将为您提供myArray
变量的精确副本。
请注意,这只是黑暗中的另一次狂野刺杀,但我现在已经多考虑了一下。如果我对此错了,请随意纠正我...我总是乐于学习。如果事实证明这是真的,也请告诉我,因为这无疑会迟早给我带来陷阱
答案 1 :(得分: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