像这样声明数组的真正区别是什么:
var myArray = new Array();
和
var myArray = [];
有一个重要的区别尚未提及。
由此:
new Array(2).length // 2 new Array(2)[0] === undefined // true new Array(2)[1] === undefined // true
您可能认为new Array(2)等同于[undefined, undefined],但事实并非如此!
new Array(2)
[undefined, undefined]
让我们尝试map():
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中没有任何真正的元素。
Array(len)
length
len
Function map(),根据规范 22.1.3.15 将首先检查HasProperty然后调用回调,但事实证明:
HasProperty
new Array(2).hasOwnProperty(0) // false [undefined, undefined].hasOwnProperty(0) // true
这就是为什么您不能期望任何迭代函数在从new Array(len).
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 ]
更新:它已经修复了。Chrome 现在打印为:
new Array(2) // (2) [empty × 2]
有区别,但在该示例中没有区别。
使用更详细的方法:new Array()在参数中确实有一个额外的选项:如果您将一个数字传递给构造函数,您将获得一个该长度的数组:
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。
new Array(5)
undefined
Array
array.length