声明 JavaScript 数组时“Array()”和“[]”有什么区别?
声明如下数组之间的真正区别是什么:
var myArray = new Array();
和
var myArray = [];
有区别,但该示例中没有区别。
使用更详细的方法:
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
进行计算变得困难。
使用隐式数组和数组构造函数创建数组之间的区别很微妙,但很重要。
当您使用
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...
有一个重要的区别,还没有答案提到。
从这个:
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]