2016-12-06 55 views
2

有人能向我解释为什么以下的Javascript控制台发生(节点7.2.0):例如,在JavaScript数组差异不同初始化方法

阵列I具有比例如II和III

不同的行为实例我

> var x = new Array(3).fill(new Array(2).fill(0)) 
> x 
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ] 
> x[0][0] = 1; 
> x 
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ] 

例Ⅱ

> var y = [...new Array(3)].map(()=>{return [...new Array(2)].map(()=>0)}) 
> y 
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ] 
> y[0][0] = 1 
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ] 

实施例III

> var y = [] 
> y.push([ 0, 0 ]) 
> y.push([ 0, 0 ]) 
> y.push([ 0, 0 ]) 
> y 
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ] 
> y[0][0] = 1 
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ] 

看来不同的方式来初始化数组将使阵列的不同的行为。我很困惑,并提前感谢你。

回答

7

array.fill()返回已修改的数组,因此您要用对同一数组的多个引用填充数组。这就是为什么当你在一个地方修改它时,它会自动显示在其他地方。

第一个例子是相当于做类似:

var arr = [ 0, 0 ]; 
var x = [ arr, arr, arr ]; 
+0

我不这么认为,我特别使用了new运算符来为fill函数创建一个新数组,以避免使用相同的引用。 – weiway

+4

'new Array()'创建一个*数组* *。 array.fill()不会创建副本,它只是将数组元素分配给传递给它的任何内容(在本例中为单个数组)。 – mscdex

0

的原因不同的是,在JS,对象(包括数组)不会被复制,它们被链接。在例子I中,你用一个数组填充数组。

> var x = new Array(3).fill(new Array(2).fill(0)) 
// You have filled x with three links to the same array 
> x 
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ] 
> x[0][0] = 1; 
// You have now modified the actual array, this change is reflected in all the links to it. 
> x 
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ] 

你在做什么是一样的做:

var a = [ 0, 0 ] 
var x = [ a, a, a ] 

OR

var a = [ 0, 0 ] 
var x = [] 
x.push(a) 
x.push(a) 
x.push(a) 

BTW,使用new Array()一般是不好的做法。数组文字语法没有任何好处。此外,使用new Array(n)会在您的阵列中产生“空插槽”,这是非常奇怪的,如果您未填满所有插槽,可能会在程序中导致问题。