不同初始化方法的Javascript数组差异

时间:2016-12-06 00:02:17

标签: javascript arrays node.js

有人可以向我解释为什么在Javascript控制台(节点7.2.0)中发生以下情况:

示例I中的数组与示例II和III具有不同的行为

示例I

> 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 ] ]

示例II

> 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 ] ]

似乎初始化数组的不同方法会导致数组的不同行为。我很困惑,并提前谢谢你。

2 个答案:

答案 0 :(得分:7)

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

第一个例子相当于做:

jQuery(document).ready(function($) {
    $('.ltwitch').each(function () {
        var tnick = $(this).data('tnick');
        var span = $(this).next();
        $.getJSON("https://api.twitch.tv/kraken/streams/"+tnick+"?client_id=48728413r2fdmq4i4otfjrtu9f8z2ou", function(c) {
            if (c.stream == null) {
                span.html("Offline");
            } else {
                span.html("Online");
            }
        });
    });
});

答案 1 :(得分: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)会使"空插槽"在您的数组中,非常奇怪,如果您没有填写所有广告位,可能会导致您的程序出现问题。