声明 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()的事实。

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

有一个重要的区别,就是尚未提及任何答案。

由此:

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 ,仅此而已,这意味着新创建的数组中没有任何实际元素

功能map()根据符合规范 22.1.3.15 会首先检查HasProperty然后调用回调,但事实证明:

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

这就是为什么您不能期望在从new Array(len)创建的new Array(len)上有任何迭代函数照常工作的原因

BTW,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(是一个不分配内存的快速恒定时间操作,wheras []是一个设置类型和值的线性时间操作。

有关更多信息, 下面的页面描述了为什么您永远不需要使用new Array()

您无需在 JavaScript 中使用new Object() 。请改用对象文字{} 。同样,请勿使用new Array() ,而应使用数组文字[] 。 JavaScript 中的数组不能像 Java 中的数组那样工作,使用类似 Java 的语法会使您感到困惑。

不要使用new Numbernew Stringnew Boolean 。这些形式产生不必要的对象包装。只需使用简单的文字即可。

还请检查注释 - new Array(length)形式没有任何有用的作用(至少在当今的 JavaScript 实现中)。

为了更好地理解[]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 上的 Google Chrome 控制台。

第一个是默认的对象构造函数调用。您可以根据需要使用其参数。

var array = new Array(5); //initialize with default length 5

第二个使您能够创建非空数组:

var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.

我可以从基于 Fredrik 的好例子的示例开始,以更具体的方式进行解释。

var test1 = [];
test1.push("value");
test1.push("value2");

var test2 = new Array();
test2.push("value");
test2.push("value2");

alert(test1);
alert(test2);
alert(test1 == test2);
alert(test1.value == test2.value);

我只是向数组添加了另一个值,并发出了四个警报:第一个和第二个是给我们存储在每个数组中的值,以确保这些值。他们将返回相同的!现在尝试第三个,它返回 false,这是因为

JS 将test1视为具有数组数据类型的 VARIABLE ,并将test2视为具有数组功能OBJECT,这里几乎没有什么区别。

第一个区别是,当我们调用 test1 时,它会不加考虑地调用变量,它只是返回存储在此变量中的值,而不管其数据类型!但是,当我们调用 test2 时,它将调用Array()函数,然后将其“推入”值存储在其“Value”属性中,并且当我们警告 test2 时,也会发生同样的情况,它返回数组对象的“Value”属性。

因此,当我们检查 test1 是否等于 test2 时,它们将永远不会返回 true,一个是函数,另一个是变量(具有数组类型),即使它们的值相同!

为确保这一点,请尝试添加了. value 的第四个警报。它将返回 true。在这种情况下,我们告诉 JS“不管容器的类型是功能还是变量,请比较存储在每个容器中的值,然后告诉我们您所看到的!” 正是这样。

我希望我清楚地说出了这个主意,并对我的英语不好对不起。

初始化没有任何长度的数组时没有区别。因此var a = []var b = new Array()是相同的。

但是,如果您使用var b = new Array(1);这样的长度来初始化数组var b = new Array(1); ,它将数组对象的长度设置为 1。因此,它等效于var b = []; b.length=1;

每当您执行 array_object.push 时,这都会成问题,它会在最后一个元素之后添加项目并增加长度。

var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2

var v = [];
a.push("hello world");
console.log(b.length); // print 1

第一个是默认的对象构造函数调用,主要用于动态值。

var array = new Array(length); //initialize with default length

创建静态值时使用第二个数组

var array = [red, green, blue, yellow, white]; // this array will contain values.