像这样声明一个数组的真正区别是什么:
var myArray = new Array();
and
var myArray = [];
像这样声明一个数组的真正区别是什么:
var myArray = new Array();
and
var myArray = [];
当前回答
奇怪的是,new Array(size)几乎比Chrome中的[]快2倍,在FF和IE中也差不多(通过创建和填充数组来衡量)。只有知道数组的大致大小才重要。如果添加的项比给定的长度多,性能提升就会丧失。
更准确地说:Array(是一个不分配内存的快速常量时间操作,而[]是一个设置类型和值的线性时间操作。
其他回答
有一个重要的区别,目前还没有答案提到。
从这个:
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]
使用的区别
var arr = new Array(size);
Or
arr = [];
arr.length = size;
在这个问题上已经讨论得够多了。
我想添加速度问题-目前最快的方式,在谷歌chrome是第二个。
但请注意,这些东西往往会随着更新而发生很大变化。此外,不同浏览器的运行时间也不同。
例如-我提到的第二个选项,在chrome上运行200万[ops/秒],但如果你在mozilla dev上尝试,你会得到一个惊人的更高的速度2300万。
无论如何,我建议你每隔一段时间在不同的浏览器(和机器)上检查一下,使用站点本身
有关更多信息,下面的页面描述了为什么永远不需要使用new Array()
你永远不需要使用new Object()在 JavaScript。使用对象文字{} 代替。同样,不要使用new Array(), 使用数组文字[] 代替。JavaScript中的数组可以工作 不像Java中的数组,而且 使用类似java的语法 迷惑你。 不使用新数字,新字符串,或 新布尔。这些形式产生 不必要的对象包装。只使用 而是简单的字面量。
还要查看注释——新的Array(length)表单没有任何有用的用途(至少在今天的JavaScript实现中)。
使用隐式数组创建数组与使用数组构造函数创建数组之间的区别很微妙,但很重要。
创建数组时使用
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…
我可以用更具体的方式来解释这个基于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视为具有数组数据类型的变量,将test2视为具有数组功能的对象,并且 这里有一些细微的区别。
第一个区别是,当我们调用test1时,它会不加思考地调用一个变量,它只返回存储在这个变量中的值,而不管它的数据类型! 但是,当我们调用test2时,它会调用Array()函数,然后将我们的“pushing”值存储在它的“Value”属性中,当我们提醒test2时也会发生同样的情况,它会返回数组对象的“Value”属性。
因此,当我们检查test1是否等于test2时,它们当然永远不会返回true,一个是函数,另一个是变量(具有数组类型),即使它们具有相同的值!
为了确保这一点,请尝试第4个警告,并将.value添加到它;它将返回true。在这种情况下,我们告诉JS“不管容器的类型是函数还是变量,请比较存储在每个容器中的值,并告诉我们你看到了什么!”这就是所发生的事情。
我希望我已经说得很清楚了,抱歉我的英语不好。