如何在JavaScript中初始化数组的长度?

我读过的大多数JavaScript教程(包括w3schools和devguru )都表明,你可以通过使用var test = new Array(4);将一个整数传递给Array构造函数来初始化一个具有一定长度的数组var test = new Array(4); 句法。

在我的js文件中使用这个语法后,我通过jsLint运行了一个文件,它吓坏了:

错误:第1行字符22的问题:预期')',而是看到'4'。
var test = new Array(4);
第1行字符23的问题:预期';' 而是看到')'。
var test = new Array(4);
第1行字符23:预期标识符,而是看到')'。

通过阅读jsLint对其行为的解释 ,看起来jsLint并不喜欢new Array()语法,而是在声明数组时更喜欢[]

所以我有几个问题。 首先,为什么? 我是否使用new Array()语法来运行任何风险? 是否有浏览器不兼容,我应该知道? 其次,如果我切换到方括号的语法,是否有任何方式来声明一个数组,并将其长度全部在一行,或者我必须做这样的事情:

 var test = []; test.length = 4; 
  1. 你为什么要初始化长度? 理论上这是没有必要的。 它甚至可能导致混淆行为,因为所有使用length来查找数组是否为空的testing都将报告数组不为空。
    一些 testing表明,如果数组填充后,设置大数组的初始长度可能会更有效,但是性能增益(如果有的话)在浏览器之间似乎有所不同。

  2. jsLint不喜欢new Array()因为constructer是不明确的。

     new Array(4); 

    创build一个长度为 4的空数组

     new Array('4'); 

    创build一个包含值 '4'的数组。

关于你的评论:在JS中,你不需要初始化数组的长度。 它dynamic增长。 你可以将这个长度存储在一些variables中,例如

 var data = []; var length = 5; // user defined length for(var i = 0; i < length; i++) { data.push(createSomeObject()); } 
  • Array(5)给你一个长度为5但没有值的数组,因此你不能迭代它。

  • Array.apply(null, Array(5)).map(function () {})给你一个长度为5,未定义为值的数组,现在可以迭代。

  • Array.apply(null, Array(5)).map(function (x, i) { return i; })给你一个长度为5,值为0,1,2,3,4的数组。

  • Array(5).forEach(alert)什么都不做, Array.apply(null, Array(5)).forEach(alert)给你5个提醒

  • ES6给我们Array.from现在你也可以使用Array.from(Array(5)).forEach(alert)

  • 如果你想初始化一个特定的string值, Array.from('abcde')Array.from('x'.repeat(5))很好知道…

有了ES2015 .fill()你现在可以简单地做到:

 //n is the size you want to initialize your array Array(n).fill(0) 

这比Array.apply(0, new Array(n)).map(i => 0)更简洁Array.apply(0, new Array(n)).map(i => 0)

这将初始化长度属性为4:

 var x = [,,,,]; 

我很惊讶没有一个function的解决schemebuild议,让您设置在一行的长度。 以下是基于UnderscoreJS:

 var test = _.map(_.range(4), function () { return undefined; }); console.log(test.length); 

出于上述原因,我会避免这样做,除非我想初始化数组到特定的值。 有趣的是,还有其他一些库实现了包括Lo-dash和Lazy在内的各种性能特征。

(这可能是更好的评论,但太长了)

所以,在阅读完这篇文章之后,我很好奇预分配实际上是否更快,因为理论上应该是这样。 但是,这个博客提供了一些build议,反对它http://www.html5rocks.com/en/tutorials/speed/v8/

所以还是不确定,我就试了一下。 而事实certificate,事实上它似乎更慢。

 var time = Date.now(); var temp = []; for(var i=0;i<100000;i++){ temp[i]=i; } console.log(Date.now()-time); var time = Date.now(); var temp2 = new Array(100000); for(var i=0;i<100000;i++){ temp2[i] = i; } console.log(Date.now()-time); 

这段代码在几次临时运行后产生以下结果:

 $ node main.js 9 16 $ node main.js 8 14 $ node main.js 7 20 $ node main.js 9 14 $ node main.js 9 19 
 var arr=[]; arr[5]=0; alert("length="+arr.length); // gives 6 

这个代码演示了不应该使用new Array的原因:

 var Array = function () {}; var x = new Array(4); alert(x.length); // undefined... 

其他一些代码可能会混淆数组variables。 我知道这有点牵强,任何人都会写这样的代码,但仍然…

而且,正如Felix King所说的,界面有点不一致,可能会导致一些非常难以跟踪的错误。

如果你想要一个长度为= x的数组,填充未定义的(如new Array(x)会做的),你可以这样做:

 var x = 4; var myArray = []; myArray[x - 1] = undefined; alert(myArray.length); // 4 

数组的构造函数有一个模糊的语法 ,JSLint只是伤害了你的感觉。

此外,您的示例代码已损坏,第二个var语句将引发一个SyntaxError 。 你正在设置数组test的属性length ,所以不需要另一个var

就你的select而言, array.length是唯一的“干净的”。 问题是,为什么你需要在第一个地方设置大小? 尝试重构你的代码来摆脱这种依赖。

请人们不要放弃你以前的习惯。 在分配内存一次,然后使用该数组中的条目(如旧)一样,复杂度有很大的差异,并且随着数组的增长分配很多次(这是系统在其他build议的方法下不可避免地要做的事情) 。

当然,这些都不重要,除非你想用较大的数组做一些很酷的事情。 然后呢。

目前来看,JS似乎还没有select设置数组的初始容量,我使用以下…

 var newArrayWithSize = function(size) { this.standard = this.standard||[]; for (var add = size-this.standard.length; add>0; add--) { this.standard.push(undefined);// or whatever } return this.standard.slice(0,size); } 

有涉及的权衡:

  • 这个方法与第一次调用函数的时间一样长,但是稍后调用的时间很less(除非要求更大的数组)。
  • standardarrays会永久保留您所要求的最大arrays的空间。

但是,如果它适合你在做什么可以有一个回报。 非正式的时间放在

 for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;} 

在相当快的速度(大约50毫秒的10000给与n = 1000000大约需要5秒),和

 for (var n=10000;n>0;n--) { var b = [];for (var add=10000;add>0;add--) { b.push(undefined); } } 

在一分钟之内(对于在同一台镀铬控制台上的10000个大约90秒,或者大约2000倍慢)。 那不仅仅是configuration,而且是万之推动,for循环等。

这是另一个解决scheme

 var arr = Array.apply( null, { length: 4 } ); arr; // [undefined, undefined, undefined, undefined] (in Chrome) arr.length; // 4 

apply()的第一个参数是一个这个对象绑定,我们不关心这个,所以我们把它设置为null

Array.apply(..)正在调用Array(..)函数,并将{ length: 3 }对象的值作为其参数传播。

如上所述,使用new Array(size)有点危险。 不要直接使用它,把它放在“数组创build器函数”中。 你可以很容易地确定这个函数是没有bug的,并且避免了直接调用new Array(size)的风险。 另外,你可以给它一个可选的默认初始值。 这个createArray函数的确如此:

 function createArray(size, defaultVal) { var arr = new Array(size); if (arguments.length == 2) { // optional default value for (int i = 0; i < size; ++i) { arr[i] = defaultVal; } } return arr; } 

您可以使用array.length = youValue来设置数组的长度

所以会是的

 var myArray = []; myArray.length = yourValue;