似乎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]]
)。
为什么它会这样?
答案 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被“指出”的东西并没有改变。