JavaScript数组无法正常填充

时间:2011-08-08 20:57:41

标签: javascript arrays google-chrome-extension contextmenu

我正在制作一个使用上下文菜单作为主要用户界面的Google Chrome扩展程序。每个菜单项触发相同的内容脚本,但具有不同的参数。我基本上做的是以JSON对象的形式存储每个项目(及其相应的数据),具有以下形式:

{name, parent_id, rule_number, meta_array[], childCount}

name,child_count和parent_id用于在构建上下文菜单时创建层次结构。传递给脚本的数据是rule_number(int)和meta_array(字符串数组)。所有这些对象都存储在名为indexData []的数组中。

单击菜单项时,提供的id仅用作“indexData”数组中的索引,以获取正确的数据并将其传递给脚本。

例如:

// Iterates through the objects
for(var j = 0; j < objectsArray.length; j++) {

// Context menu created with unique id
var id = chrome.contextMenus.create({
"title": objectArray[j].name, 
"onclick": injectScript,  
"parentId": objectsArray[j].parent_id });

// Stores the objects at the corresponding index
indexData[id] = objectsArray[j]; }

现在,经常会有一大堆特定的数据。每次我希望它们作为菜单的一部分时,不是每次都列出这些元素,而是向每个需要这组数据作为其子元素的JSON对象添加一个布尔参数。创建菜单时,如果此布尔值设置为true,则调用函数。然后,该脚本只迭代一个单独的对象列表,并使它们成为该父对象的子项。创建的孩子甚至从父对象继承了某些东西。

例如,如果一个父对象有一个像[“1”,“2”,“3”,“4”]这样的meta_array,那么它的子节点看起来都像[“1”,“2”,custom_children_data [3],“4”]。

问题是这最后一部分不起作用。虽然创建的子项很好并且名称正确,但与它们关联的数据是错误的。它始终是该单独列表中最后一个对象的数据。这就是函数的样子:

// Iterate through children list
for(var i = 0; i < separateList.length; i++){ 

// Just copying the passed parent object's data
var parentData = data; 

var id = chrome.contextMenus.create({
"title": separateList[i].name, // Get item [i] of the children list (works fine) 
"onclick": injectScript, 
"parentId": parentId           // Will become a child of parent object
 });


// Trying to change some data, this is where things go wrong.
parentData.meta[2] =  separateList[i].meta; 

// Save in indexData
indexData[id] = parentData; }

在循环的第一次迭代中,parentData.meta [2]从列表中获取正确的值,然后将此值保存在indexdata中。但是在后续的迭代中,indexData中已经存在的所有值都被刷掉了,取而代之的是从列表中读取的最新数据。读取最后一个值时,indexData中所有新添加的元素都会更改为最后一个值,这解释了我的问题。但为什么它会这样做呢?在这种情况下,Java会以某种方式通过地址而不是值或某种方式处理数组吗?

也许我错过了一些非常明显的东西,但经过多次尝试后我仍然无法正常工作。我试图在我的描述中尽可能具体,但我可能忘记提及一些事情,所以如果你想知道其他任何事情,请随便提出,我会很乐意提供更多细节。

感谢。

2 个答案:

答案 0 :(得分:3)

我的猜测是,这就是你的问题所在:

// Just copying the passed parent object's data
var parentData = data; 

事实上,这并不是复制数据;相反,它会创建对data的引用,因此对parentData所做的任何修改也会更改data。如果您想要“克隆”data对象,则必须手动执行此操作,或者找到具有此功能的库。

答案 1 :(得分:3)

问题是indexData[id] = parentData你在哪里使indexData [id]成为对parentData的引用,然后在循环的下一次迭代中修改parentData。

由于父数据不是简单数组(它至少包含一个数组或对象),因此不能简单地使用slice(0)进行复制。您必须编写自己的复制功能,或使用具有一个功能的库。