声明 JavaScript 数组时,“Array()”和“[]”之间有什么区别?

IT技术 javascript arrays declaration
2021-01-20 05:39:52

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

var myArray = new Array();

var myArray = [];
6个回答

有区别,但在那个例子中没有区别。

使用更详细的方法: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计算变得难以依赖

是的,但在我添加它们的大多数地方也不需要分号或换行符。这是关于一致性和易读性。你知道,恕我直言。
2021-03-28 05:39:52
重要的是,使用 new 运算符会导致解释器采取各种额外的步骤进入全局范围,查找构造函数,调用构造函数并分配结果......在大多数情况下这将是aa 运行时数组。您可以通过使用 [] 来避免查找全局构造函数的开销。它可能看起来很小,但是当您在应用程序中追求近乎实时的性能时,它会有所作为。
2021-03-29 05:39:52
但是正如您的回答中所指出的,只有当您完全疯了并覆盖 Array 函数时才会有所不同..?
2021-03-31 05:39:52
存在巨大的性能差异:jsperf.com/create-an-array-of-initial-size/2
2021-04-02 05:39:52
这有点不对。new Array() 和 [] 之间有一个非常重要的区别,我将在我的回答中详细说明。
2021-04-06 05:39:52

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

当您使用创建数组时

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().

[]如果您知道您只需要一个数组,那么最好只使用它我也不建议四处走动并重新定义数组...

好吧,很高兴知道我想。什么样的人会覆盖数组类,我不知道......
2021-03-12 05:39:52
值得注意的是,新的 Array(size) 比使用 [] 表示法的其他可能方法更快。来源:jsperf.com/create-an-array-of-initial-size/2
2021-03-16 05:39:52
不幸的是,该测试准备不当。它正在测试数组的初始化,然后是数组的初始化,然后是数组访问。没有控制来证明浏览器实际上预先分配了内存(规范没有说他们必须这样做)。如果我们可以假设数组访问是恒定的,并且在两个示例中大部分时间都用于分配内存,那么如果您要实例化数百万个数组,则 [] 可能更可取。 jsperf.com/array-instanciation
2021-03-25 05:39:52
JavaScript 可能发生的那种全局污染的好例子。
2021-04-01 05:39:52
你是绝对正确的。只有疯子才会覆盖数组类。现在花点时间考虑一下使用 new Array() 使解释器为支持这些疯子所做的所有额外工作。我只是和 [] 一起避免它。
2021-04-03 05:39:52

有一个重要的区别,尚未提到答案。

由此:

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]
看起来我之前评论的答案是“Spread operator”:javascript.info/rest-parameters-spread-operator
2021-03-13 05:39:52
@RobertoAndrade 这是有道理的,因为传播运算符需要读取条目,以便它可以应用这种复制......并undefined像往常一样读取这样的空槽返回
2021-03-13 05:39:52
这是有道理的,我只是遇到了一个不同的结构,我找不到其文档参考:从结果的角度来看[...Array(2)],这等效于[undefined, undefined]
2021-03-15 05:39:52
相当于new Array(2)应该是[,,],不是[undefined, undefined],不是?
2021-04-01 05:39:52

奇怪的是,new Array(size)它几乎比[]Chrome快 2 倍,在 FF 和 IE 中几乎相同(通过创建和填充数组来衡量)。仅当您知道数组的大致大小时才重要。如果您添加的项数超过您给定的长度,则性能提升将丢失。

更准确地说:Array(是不分配内存的快速恒定时间操作,[]而是设置类型和值的线性时间操作。

我已经在 Node.js 中对其进行了大量测试:当您需要将一些项目放入数组时,new Array(length)在 0 <= size <= ~1000,在 size > ~1000 上获胜[]
2021-04-07 05:39:52
2021-04-09 05:39:52

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

你永远不需要new Object()在 JavaScript 中使用。请改用对象字面量{}同样,不要使用new Array()[] 而是使用数组文字JavaScript 中的数组与 Java 中的数组不同,使用类似 Java 的语法会让您感到困惑。

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

还要查看评论 - 该new Array(length)表单没有任何有用的用途(至少在今天的 JavaScript 实现中)。

Crockford 不喜欢使用“new”关键字在 Javascript 中创建对象的新实例。在讲座中,他表示他认为这会造成歧义,并且不适合 Javascript 的原型样式继承。他特别指的是用户创建的对象构造函数,但鉴于这种信念,很容易理解为什么他建议您不要在有替代语法的情况下将其与内置函数一起使用。
2021-03-23 05:39:52
@Alan Storm:至少对于 Number、String 和 Boolean,他说“这些形式会产生不必要的对象包装器”,但我想这不适用于 Array。
2021-04-05 05:39:52
Crockford 也说使用 [] 而不是 new Array()。不幸的是,他没有在链接的文章中说明原因。我认为这只是空间和速度的问题。javascript.crockford.com/code.html
2021-04-08 05:39:52