在“for”循环中填充多维数组(javascript)

时间:2012-12-03 21:57:51

标签: javascript arrays optimization for-loop multidimensional-array

似乎JavaScript在某种程度上试图优化代码,因此如果我们想要在循环中使用一维数组(largeArr)的值更改来填充多维数组(smallArr)并使用此代码:

largeArr = []
smallArr = []

for (i=0; i<2; i++)
{
    smallArr[0]=i
    smallArr[1]=2*i

    largeArr[i]=smallArr
}

我们得到了意外的结果:largeArr=[[1,2],[1,2]](必须是[[0,0],[1,2]])。因此,Javascript首先计算smallArr值,然后填充largeArr。 为了获得正确的结果,我们必须在循环中声明smallArr

largeArr = []

for (i=0; i<2; i++)
{
    smallArr = []
    smallArr[0]=i
    smallArr[1]=2*i

    largeArr[i]=smallArr
}

然后按预期工作(largeArr=[[0,0],[1,2]])。

为什么它会这样?

4 个答案:

答案 0 :(得分:4)

因为指针,这就是原因。 Javascript采用Java和C,以此(仅限于此)方式。当你完成作业

largeArr[i] = smallArr

你正在指定一个指针。指针细分:

在C中,(在较小程度上,Java和Javascript)你没有基本的数组类型 - 相反,数组指向内存中的空间,你可以用你想要的任何信息填充该空间(或者更确切地说,你已宣布)。指针存在于内存中的方式?一个四(或八个或两个,取决于您的系统)字节内存地址,它告诉编译器/解析器在哪里获得适当的信息。所以,当你在那里做那个任务时,你会告诉它:“嘿,将largeArr [i]设置为等于smallArr的内存地址。”因此,当您对smallArr进行更改时,每次取消引用数组时都会反映它 - 因为它实际上是相同的数组。但是当你这样做时:

smallArr = [] 

在循环内部,你说,“创建一个新数组,并将smallArr设置为等于该数组的地址。”这样,阵列就会分开。

答案 1 :(得分:0)

使用行largeArr[i]=smallArr,您可以将i属性设置为对smallArr的引用。你做复制它。最后,largeArr的所有属性都将指向同一个属性smallArr,您每次都会覆盖这些值。

通过初始化每个循环转弯smallArr,您可以创建新对象;因此largeArr的每个属性都将指向不同的数组。顺便说一下,它是赋值,而不是声明 - 你会(并且应该)使用var statement将变量声明为本地(到函数)。< / p>

答案 2 :(得分:0)

在最后的迭代中

smallArr[0]=i
smallArr[1]=2*i  

(其中i=1)上面的代码转换为:

smallArr[0]=1
smallArr[1]=2

你的大阵列不是这个:

[smallArr, smallArr]

导致意外结果:

[[1, 2], [1, 2]]

在javascript对象中通过引用复制(一种c样式指针) 为了获得所需的结果,必须按值复制数组,或在每个循环中分配不同的数组:

var largeArr = [];

for (i=0; i<2; i++)
   largeArr[i] = [[i, 2*i]];

答案 3 :(得分:0)

如上所述分配数组引用时,您不是要分配该数组的,而只是指定数组。

将其视为指针。 largeArr [0]和largeArr [1]指向smallArr,循环迭代只是改变smallArr的内容。 largeArr被“指出”的东西并没有改变。