像这样声明一个数组的真正区别是什么:

var myArray = new Array();

and

var myArray = [];

当前回答

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

创建数组时使用

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”。第二个则不会。你最终会看到undefined。您还会注意到b包含所有原生Array对象函数,例如push,而另一个则不包含。

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

如果你只是想要一个数组,最好使用[]。我也不建议到处去重新定义Array…

其他回答

使用Array构造函数创建一个所需长度的新数组,并将每个下标填充为undefined,将赋值给变量one的数组创建您为其提供信息的下标。

为了更好地理解[]和new Array():

> []
  []
> new Array()
  []
> [] == []
  false
> [] === []
  false
> new Array() == new Array()
  false
> new Array() === new Array()
  false
> typeof ([])
  "object"
> typeof (new Array())
  "object"
> [] === new Array()
  false
> [] == new Array()
  false

以上结果来自Windows 7上的谷歌Chrome控制台。

我发现了这两种结构之间的一个区别,这让我很难受。

假设我有:

function MyClass(){
  this.property1=[];
  this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();

在现实生活中,如果我这样做:

MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');

我最后得出的结论是:

MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']

我不知道语言规范说应该发生什么,但如果我想让我的两个对象在我的对象中有唯一的属性数组,我必须使用new Array()。

事情远比看上去的复杂。大多数其他答案是正确的,但也…

新数组(n)

允许引擎为n个元素重新分配空间 为创建数组而优化 创建的数组被标记为稀疏数组具有最少的性能数组操作,这是因为每个索引访问都必须检查边界,查看是否存在值并遍历原型链 如果数组被标记为稀疏,就没有办法返回(至少在V8中),它在生命周期内总是会变慢,即使你在1毫秒或2小时后用内容填充它(打包的数组)也没关系

[1, 2, 3] | | []

创建的数组被标记为已打包(除非使用delete或[1,,3]语法) 针对数组操作进行了优化(用于.., forEach, map等) 随着数组的增长,引擎需要重新分配空间

对于旧版本的浏览器可能不是这样。

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

从这个:

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

你可能认为新的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)的任务只是创建一个新数组,其属性长度设置为参数len,这就意味着在这个新创建的数组中没有任何实际元素。

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