像这样声明数组之间的真正区别是什么:
var myArray = new Array();
和
var myArray = [];
像这样声明数组之间的真正区别是什么:
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()
.
[]
如果您知道您只需要一个数组,那么最好只使用它。我也不建议四处走动并重新定义数组...
有一个重要的区别,尚未提到答案。
由此:
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
,就是这样,这意味着在这个新创建的数组中没有任何真正的元素。
Function map()
,根据规范 22.1.3.15 将首先检查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]
奇怪的是,new Array(size)
它几乎比[]
Chrome快 2 倍,在 FF 和 IE 中几乎相同(通过创建和填充数组来衡量)。仅当您知道数组的大致大小时才重要。如果您添加的项数超过您给定的长度,则性能提升将丢失。
更准确地说:Array(
是不分配内存的快速恒定时间操作,[]
而是设置类型和值的线性时间操作。
有关更多信息,以下页面描述了为什么您永远不需要使用new Array()
你永远不需要
new Object()
在 JavaScript 中使用。请改用对象字面量{}
。同样,不要使用new Array()
,[]
而是使用数组文字。JavaScript 中的数组与 Java 中的数组不同,使用类似 Java 的语法会让您感到困惑。不要使用
new Number
、new String
、 或new Boolean
。这些形式会产生不必要的对象包装器。只需使用简单的文字即可。
还要查看评论 - 该new Array(length)
表单没有任何有用的用途(至少在今天的 JavaScript 实现中)。