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

时间:2009-05-31 11:23:33

标签: javascript arrays declaration

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

var myArray = new Array();

var myArray = [];

18 个答案:

答案 0 :(得分:873)

存在差异,但该示例没有区别。

使用更详细的方法: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

;

答案 1 :(得分:755)

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

使用

创建数组时
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,而另一个则不包含。{/ p>

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

如果您只是想要一个数组,那么最好只使用[]。我也不建议四处走动并重新定义阵列......

答案 2 :(得分:72)

没有人提到过,存在巨大差异。

您可能认为new Array(2)之前等同于[undefined, undefined],因为我们有

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

但不是!

让我们试试map()

[undefined, undefined].map(e => 1)  // [1, 1]
new Array(2).map(e => 1)            // "(2) [undefined × 2]" in Chrome

请参阅?它有所不同!但那为什么呢?

根据ES6规范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) 创建的数组一样正常工作。

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 ]

我已向Chrome提交了一个问题,要求他们修复这个令人困惑的日志: https://bugs.chromium.org/p/chromium/issues/detail?id=732021

更新:它已经修好了。 Chrome现在记录为

new Array(2)             // (2) [empty × 2]

答案 3 :(得分:47)

奇怪的是,new Array(size)几乎比Chrome中的[]快2倍,在FF和IE中大约相同(通过创建和填充数组来衡量)。只有了解阵列的大致尺寸才有意义。如果您添加的项目数量超过了您提供的项目长度,则会失去性能提升。

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

答案 4 :(得分:36)

有关详细信息,the following page说明了您永远不需要使用new Array()

的原因
  

您永远不需要使用new Object()   JavaScript的。使用对象文字{}   代替。同样,请勿使用new Array(),   使用数组文字[]   代替。 JavaScript中的数组工作   没有像Java中的数组那样   使用类似Java的语法   让你困惑。

     

请勿使用new Numbernew String或   new Boolean。这些形式产生   不必要的对象包装器。只是用   简单的文字而不是。

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

答案 5 :(得分:9)

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

答案 6 :(得分:8)

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

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

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

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

答案 7 :(得分:5)

我可以从更具体的方式开始解释,这个例子基于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“忽略容器的类型,无论是功能还是变量,请比较存储在每个容器中的值并告诉我们你看到了什么!”这正是发生的事情。

我希望我能清楚地说出这个想法,并为我糟糕的英语道歉。

答案 8 :(得分:2)

除了眼神之外,还有更多的东西。其他大多数答案都是正确的

new Array(n)

  • 允许引擎为n元素重新分配空间
  • 针对数组创建
  • 进行了优化
  • 创建的数组标记为 sparse ,该数组具有最低的数组操作性能,这是因为每个索引访问都必须检查边界,查看值是否存在并遍历原型链 < / li>
  • 如果将数组标记为稀疏,则无法回退(至少在V8中如此),即使在1ms或2小时后填充了内容(压缩数组),它在其生命周期中也总是会变慢。没关系

[1, 2, 3] || []

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

对于较旧的浏览器版本/浏览器而言,可能不是

答案 9 :(得分:2)

The first one is the default object constructor call.mostly used for dynamic values.

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

the second array is used when creating static values

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

答案 10 :(得分:2)

没有什么大的区别,他们基本上做同样的事情,但以不同的方式做,但继续阅读,看看W3C的这句话:

var cars = ["Saab", "Volvo","BMW"];

var cars = new Array("Saab", "Volvo", "BMW");
  

上面两个例子完全相同。没有必要使用   新的Array()。
为简单起见,可读性和执行速度,请使用   第一个(数组文字方法)。

但与此同时,使用new Array语法创建新数组被认为是一种不好的做法:

  

避免使用新的Array()

     

无需使用JavaScript的内置数组构造函数   new Array()。
  请改用[]   这两个不同的语句都创建了一个名为的新空数组   分:

var points = new Array();         // Bad
var points = [];                  // Good 
  

这两个不同的语句都创建了一个包含6的新数组   数:

var points = new Array(40, 100, 1, 5, 25, 10); // Bad    
var points = [40, 100, 1, 5, 25, 10];          // Good
  

关键字只会使代码复杂化。它也可以产生一些   意想不到的结果:

var points = new Array(40, 100);  // Creates an array with two elements (40 and 100)
  

如果删除其中一个元素该怎么办?

var points = new Array(40);       // Creates an array with 40 undefined elements !!!!!

所以基本上不被认为是最佳实践,也有一个小的差异,你可以将长度传递给new Array(length)这样,这也不是推荐的方法。

答案 11 :(得分:1)

好吧,var x = new Array()var x = []的不同之处在于某些功能,我只解释其中两个最有用的功能。

在解释差异之前,我将首先设定一个基础。当我们使用x = []定义一个数据类型为Array的新变量时,它继承了属于该数组原型的所有方法,这与扩展类非常相似(但不完全相同)。但是,当我们使用x = new Array()时,它会初始化分配给变量x的数组原型的克隆。

现在让我们看看有什么区别

第一个区别是使用new Array(x)(其中x是整数)初始化x个未定义值的数组,例如new Array(16)将初始化具有16个项目的数组,所有这些项目均未定义。当您异步填充预定义长度的数组时,这非常有用。 例如(再次:)),假设您获得了100个竞争者的结果,并且是从远程系统或数据库异步接收它们的,那么一旦获得,您就需要根据排名在数组中分配它们每个结果。在这种极少数情况下,您将执行类似myArray[result.rank - 1] = result.name的操作,因此将等级1设置为索引0,依此类推。

第二个不同之处是,如您所知,使用new Array()可以实例化数组原型的全新克隆并将其分配给变量,这使您可以做一些魔术(不建议顺便说一句)。这样做的魔力在于您可以覆盖传统数组方法中的特定方法。因此,例如,您可以设置Array.push方法以将新值推入数组的开头而不是末尾,还可以向该数组原型的特定克隆添加新方法(更好)。 。这样一来,您就可以使用自己添加的方法在整个项目中定义更复杂的数组类型,并将其用作类。

最后,如果您来自极少数关心我的应用程序的处理开销和内存消耗的人(我非常喜欢),那么您new Array()永远不会急于使用它: )。

我希望已经对野兽new Array()进行了足够的解释:)

答案 12 :(得分:1)

初始化没有任何长度的数组时没有区别。因此rv <- eventReactive(check(), { rv.haschanged(FALSE) cars[sample.int(nrow(cars), 1),] # return cars dataset as an example }) var a = []是相同的。

但是,如果初始化长度为var b = new Array()的数组,则会将数组对象的长度设置为1。因此,它等效于var b = new Array(1);

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

var b = []; b.length=1;

vs

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

答案 13 :(得分:1)

我使用[]引发了一种奇怪的行为。

我们有模型“类”,字段初始化为某个值。例如:

require([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){

   declare("MyWidget", [_WidgetBase], {
     field1: [],
     field2: "",
     function1: function(),
     function2: function()
   });    
});

我发现当用[]初始化字段时,它将由所有Model对象共享。对一个进行更改会影响所有其他操作。

使用new Array()初始化它们不会发生。对象的初始化({}与新Object()

相同

TBH我不确定我们使用的框架是否存在问题(Dojo

答案 14 :(得分:1)

据我所知,差异可以找到切片(或阵列的其他功能),如 code1 。和 code2 显示你的数组和他的实例

<强>代码1:

[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here

<强>码2:

[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true

<强>结论

你可以看到[]new Array()创建一个新的Array实例。他们都从Array.prototype获得原型函数

它们只是Array的不同实例。这解释了原因 [] != []

:)

答案 15 :(得分:1)

使用

的区别
var arr = new Array(size);

或者

arr = [];
arr.length = size;

正如在这个问题中已经讨论过的那样。

我想添加速度问题 - 当前最快的方式,google chrome是第二个。

但请注意,这些事情往往会随着更新而发生很大变化。此外,不同浏览器的运行时间也不同。

例如 - 我提到的第二个选项,在chrome上以200万[操作/秒]运行,但如果您在mozilla dev.上尝试,则会获得令人惊讶地高达2300万。

无论如何,我建议你每隔一段时间在不同的浏览器(和机器)上查看,使用网站as such

答案 16 :(得分:-1)

我发现这两个结构之间有一点不同,这让我非常努力。

我们说我有:

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

答案 17 :(得分:-3)

使用Array构造函数创建一个具有所需长度的新数组,并使用undefined填充每个索引,将指定的数组分配给变量one创建您为其提供信息的索引。