开发者问题收集

声明 JavaScript 数组时“Array()”和“[]”有什么区别?

2009-05-31
936129

声明如下数组之间的真正区别是什么:

var myArray = new Array();

var myArray = [];
3个回答

有区别,但该示例中没有区别。

使用更详细的方法: new Array() 在参数中确实有一个额外的选项:如果将数字传递给构造函数,您将获得该长度的数组:

x = new Array(5);
alert(x.length); // 5

为了说明创建数组的不同方法:

var a = [],            // these are the same
    b = new Array(),   // a and b are arrays with length 0

    c = ['foo', 'bar'],           // these are the same
    d = new Array('foo', 'bar'),  // c and d are arrays with 2 strings

    // these are different:
    e = [3]             // e.length == 1, e[0] == 3
    f = new Array(3),   // f.length == 3, f[0] == undefined

;

另一个区别是,当使用 new Array() 时,您可以设置数组的大小,这会影响堆栈大小。如果您遇到堆栈溢出( Array.push 与 Array.unshift 的性能 ),这将很有用,当数组的大小超出堆栈的大小时会发生这种情况,并且必须重新创建。因此,根据使用情况,使用 new Array() 时实际上可以提高性能,因为您可以防止溢出发生。

正如 此答案 中指出的那样, new Array(5) 实际上不会向数组中添加五个 undefined 项。它只是增加了五个项目的空间。请注意,以这种方式使用 Array 会使依赖 array.length 进行计算变得困难。

nickf
2009-05-31

使用隐式数组和数组构造函数创建数组之间的区别很微妙,但很重要。

当您使用

var a = [];
创建数组时,您正在告诉解释器创建一个新的运行时数组。根本不需要额外的处理。完成。

如果您使用:

var a = new Array();

您正在告诉解释器,我想调用构造函数“ Array ”并生成一个对象。然后它通过您的执行上下文查找要调用的构造函数,并调用它,创建您的数组。

您可能会想“嗯,这根本没关系。它们是一样的!”。不幸的是,您无法保证这一点。

请看以下示例:

function Array() {
    this.is = 'SPARTA';
}

var a = new Array();
var b = [];

alert(a.is);  // => 'SPARTA'
alert(b.is);  // => undefined
a.push('Woa'); // => TypeError: a.push is not a function
b.push('Woa'); // => 1 (OK)

在上面的例子中,第一个调用将如您所愿地提醒“SPARTA”。第二个则不会。您最终会看到未定义。您还会注意到 b 包含所有本机 Array 对象函数,例如 push ,而另一个则不包含。

虽然您可能希望发生这种情况,但它只是说明了 []new Array() 不同。

如果您知道您只想要一个数组,最好只使用 [] 。我也不建议到处重新定义 Array...

coderjoe
2009-08-13

有一个重要的区别,还没有答案提到。

从这个:

new Array(2).length           // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true

您可能认为 new Array(2) 等同于 [undefined, undefined] 但事实并非如此!

让我们尝试使用 map()

[undefined, undefined].map(e => 1)  // [1, 1]
new Array(2).map(e => 1)            // "(2) [undefined × 2]" in Chrome

看到了吗?语义完全不同!那是为什么呢?

根据 ES6 Spec 22.1.1.2, Array(len) 的工作只是创建一个新数组,其属性 length 设置为参数 len ,就是这样,这意味着这个新创建的数组中没有任何 真实元素

根据规范 22.1.3.15,函数 map() 首先会检查 HasProperty ,然后调用回调,但结果却是:

new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true

这就是为什么您不能指望任何迭代函数在由 new Array(len) 创建的数组上照常工作。

顺便说一句,Safari 和 Firefox 对这种情况有更好的“打印”功能:

// Safari
new Array(2)             // [](2)
new Array(2).map(e => 1) // [](2) 
[undefined, undefined]   // [undefined, undefined] (2) 

// Firefox
new Array(2)             // Array [ <2 empty slots> ]
new Array(2).map(e => 1) // Array [ <2 empty slots> ]
[undefined, undefined]   // Array [ undefined, undefined ]

我已经向 Chromium 提交了一个问题,并要求他们修复这个令人困惑的打印: https://bugs.chromium.org/p/chromium/issues/detail?id=732021

更新:已修复。Chrome 现在打印为:

new Array(2)             // (2) [empty × 2]
Hux
2017-06-10