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

问:

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

var myArray = new Array();

var myArray = [];

答1:

huntsbot.com – 高效赚钱,自由工作

有区别,但在该示例中没有区别。

使用更详细的方法: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() 时,您可以设置数组的大小,这会影响堆栈大小。如果您遇到堆栈溢出 (Performance of Array.push vs Array.unshift),这是很有用的,当数组的大小超过堆栈的大小时会发生这种情况,并且必须重新创建它。所以实际上,根据用例,使用 new Array() 可以提高性能,因为您可以防止发生溢出。

正如 this answer 中所指出的,new Array(5) 实际上不会将五个 undefined 项添加到数组中。它只是为五个项目增加了空间。请注意,以这种方式使用 Array 会使依赖 array.length 进行计算变得困难。

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

这有点不对。 new Array() 和 [] 之间有一个非常重要的区别,我将在我的回答中详细说明。

但正如您在回答中指出的那样,只有当您完全疯了并覆盖 Array 函数时才会有所不同..?

重要的是,使用 new 运算符会导致解释器采取各种额外的步骤进入全局范围,查找构造函数,调用构造函数并分配结果......在大多数情况下,这将是一个运行时数组。您可以通过使用 [] 来避免查找全局构造函数的开销。它可能看起来很小,但是当您在应用程序中追求近乎实时的性能时,它会有所作为。

存在巨大的性能差异:jsperf.com/create-an-array-of-initial-size/2

没错,但在我添加分号或换行符的大多数地方,您也不需要分号或换行符。这是关于一致性和易读性。你知道,恕我直言。

答2:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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

当您使用创建数组时

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() 所做的所有额外工作使解释器能够支持这些疯子。我只是和[]一起避免了这一切。

JavaScript 可能造成的全球污染的一个很好的例子。

值得注意的是,新的 Array(size) 比使用 [] 表示法的其他可能方法更快。来源:jsperf.com/create-an-array-of-initial-size/2

不幸的是,该测试准备不当。它正在测试一个数组的初始化,其中包含数组的初始化,然后是数组访问。无法控制来证明浏览器实际上是在预先分配内存(规范并没有说它们必须这样做)。如果我们可以假设数组访问是恒定的,并且在这两个示例中大部分时间都将用于分配内存,那么如果您要实例化数百万个数组,则 [] 可能更可取。 jsperf.com/array-instanciation

答3:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

有一个重要的区别尚未提及。

由此:

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) 创建的数组上照常工作。

顺便说一句,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]

这是有道理的,我只是碰到了一个不同的结构,我找不到以下的文档引用:[...Array(2)] 从结果的角度来看,它等同于 [undefined, undefined]。

看起来我之前评论的答案是“扩展运算符”:javascript.info/rest-parameters-spread-operator

@RobertoAndrade 这很有意义,因为扩展运算符将需要读取条目,以便它可以应用这样的复制......并像往常一样读取这样的空槽返回 undefined。

new Array(2) 的等价物应该是 [,,],而不是 [undefined, undefined],不是吗?

答4:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

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

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

我在 Node.js 中对其进行了很多测试:当您需要将一些项目放入数组中时,new Array(length) on 0 <= size <= ~1000, on size > ~1000 胜 []

检查这个stackoverflow.com/questions/7375120/…

答5:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

如需更多信息,the following page 说明了您从不需要使用 new Array() 的原因

你永远不需要在 JavaScript 中使用 new Object()。请改用对象文字 {}。同样,不要使用 new Array(),而是使用数组字面量 []。 JavaScript 中的数组与 Java 中的数组完全不同,使用类似 Java 的语法会让您感到困惑。不要使用新数字、新字符串或新布尔值。这些形式产生不必要的对象包装。只需使用简单的文字代替。

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

Crockford 也说使用 [] 而不是 new Array()。不幸的是,他没有在链接的文章中说明原因。我认为这只是空间和速度的问题。 javascript.crockford.com/code.html

Crockford 不喜欢使用“new”关键字在 Javascript 中创建对象的新实例。在讲座中,他表示他认为它会产生歧义,并且不适合 Javascript 的原型样式继承。他特别指的是用户创建的对象构造函数,但鉴于这种信念,很容易理解为什么他建议您不要将它与内置函数一起使用,因为有替代语法。

@Alan Storm:至少对于 Number、String 和 Boolean,他说“这些形式会产生不必要的对象包装”,但我想这不适用于 Array。

答6:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

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

但为什么 [] == [] 或 [] === [] false ?

“仅当操作数引用相同的对象时,比较对象的表达式才为真。” (来源:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)

这个答案樱桃挑选了一些例子来暗示这两个结构是相同的。此页面上的其他帖子指出了差异,例如 Array(3) 或 new Array(3) 与 [3] 不同。

答7:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

第一个是默认的对象构造函数调用。如果需要,您可以使用它的参数。

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

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

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

你可以用详细的构造函数做同样的事情: var array = new Array(1, 2, 3);

那么我猜你可以使用方括号执行 var array = [5] 但不使用构造函数,因为 var array = Array(5) 会生成一个包含 5 个元素的空数组。

cdmckay - 这是不正确的。 var a=[5] 将是一个包含单个项目的数组 - 数字 5。

@BarelyFitz:我就是这么说的。在 Bogdans 的回答中,他说构造函数调用不能用于初始化数组,但他错了。我的评论只是为了澄清您不能使用构造函数调用来初始化单个元素的数组。

@cdmckay:对不起,我误解了你的评论。澄清一下: new Array(arg) - 如果 arg 是数字,这将创建一个长度为 arg 的空数组; new Array(arg1, arg2) - 创建一个新数组并初始化数组元素。因此,如果您想创建一个包含一个数字元素的数组,如 [5],则无法使用 new Array(5) 来实现。但实际上你永远不应该使用 new Array() 所以这是一个有争议的问题。

答8:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

我可以从这个基于 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() 函数,然后它将我们的“Pushed”值存储在它的“Value”属性中,当我们警告 test2 时也会发生同样的情况,它会返回数组对象的“Value”属性。

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

为了确定这一点,请尝试第 4 个警报,并添加 .value;它会返回真。在这种情况下,我们告诉 JS “不管容器的类型,无论是函数还是变量,请比较每个容器中存储的值,并告诉我们你看到了什么!”这正是发生的事情。

我希望我清楚地表达了背后的想法,并为我糟糕的英语感到抱歉。

令人惊讶的是,如此完整而完全的废话被投票赞成。无论您如何制作数组之间的比较都是错误的,因为它比较对象身份并且它们是不同的对象。数组没有值属性。 [] 和 new Array() 相同; .value 在这两种情况下都是 undefined,比较它们总是错误的。

同意,这个答案没有任何意义,也没有显示任何内容。没有 array.value 这样的东西。 typeof [] 和 typeof new Array() 都返回 object。这就是为什么有一个名为 Array.isArray 的函数的原因之一

好吧,伙计们,我同意你的看法:)当时我写了一个完整的废话:)。现在我已经为同一个问题添加了正确答案。让我知道你看到了什么。我非常感谢您的意见。

答9:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

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

但是如果你用像 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

答10:

huntsbot.com – 高效赚钱,自由工作

这不仅仅是表面上看到的。大多数其他答案都是正确的,但也…

新数组(n)

允许引擎为 n 个元素重新分配空间

针对阵列创建进行了优化

创建的数组被标记为稀疏,它的数组操作性能最低,这是因为每个索引访问都必须检查边界,查看值是否存在并遍历原型链

如果数组被标记为稀疏,则无法返回(至少在 V8 中),它在其生命周期内总是会变慢,即使您在 1 毫秒或 2 小时后用内容(打包数组)填充它,也没关系

[1, 2, 3] || []

创建的数组被标记为打包(除非您使用 delete 或 [1,3] 语法)

针对数组操作进行了优化(用于 …、forEach、map 等)

随着阵列的增长,引擎需要重新分配空间

对于较旧的浏览器版本/浏览器,情况可能并非如此。

答11:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

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

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

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

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

原文链接:https://www.huntsbot.com/qa/qmRV/what-s-the-difference-between-array-and-while-declaring-a-javascript-ar?lang=zh_CN&from=csdn

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

猜你喜欢

转载自blog.csdn.net/kalman2019/article/details/128732223