我在JavaScript中读到的大多数关于数组的教程(包括w3schools和devguru)都建议,通过使用vartest=newArray(4)将整数传递给array构造函数,可以初始化具有一定长度的数组;语法。

在我的js文件中大量使用了这种语法后,我通过jsLint运行了其中一个文件,结果发现:

错误:第1行第22个字符出现问题:应为“)”,但看到的却是“4”。var test=新阵列(4);第1行第23个字符出现问题:应为“;”而是看到“)”。var test=新阵列(4);第1行第23个字符出现问题:应为标识符,但看到的却是“)”。

在阅读了jsLint对其行为的解释之后,jsLint似乎并不真正喜欢新的Array()语法,而是在声明数组时更喜欢[]。

所以我有几个问题:

首先,为什么?改用新的Array()语法是否会有风险?我是否应该注意到浏览器不兼容?

第二,如果我切换到方括号语法,是否有任何方法声明数组并将其长度全部设置在一行上,或者我必须这样做:

var test = [];
test.length = 4;

当前回答

这是另一个解决方案

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

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

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

其他回答

为什么要初始化长度?理论上没有必要这样做。它甚至会导致混乱的行为,因为所有使用该长度来确定数组是否为空的测试都会报告该数组不为空。一些测试表明,如果随后填充数组,则设置大数组的初始长度可能会更有效,但每个浏览器的性能增益(如果有的话)似乎有所不同。jsLint不喜欢new Array(),因为构造函数不明确。新阵列(4);创建长度为4的空数组。但是新阵列('4');创建包含值“4”的数组。

关于你的评论:在JS中,你不需要初始化数组的长度。它是动态增长的。您可以将长度存储在某个变量中,例如。

var data = [];
var length = 5; // user defined length

for(var i = 0; i < length; i++) {
    data.push(createSomeObject());
}

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

所以,读了这篇文章后,我很好奇预分配是否真的更快,因为理论上应该更快http://www.html5rocks.com/en/tutorials/speed/v8/.

所以我仍然不确定,所以我把它放在了测试中。事实证明,它似乎更慢。

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

最简单的形式是使用

Array.from({ length: 3 });

// gives you
[undefined, undefined, undefined]

与Array(3)不同,它将为您提供一个无法迭代的数组。from({length})为您提供了一个可以轻松迭代的数组。

Array.from({ length: 3 }).map((e, idx) => `hi ${idx}`);
// ['hi 1', 'hi 2', 'hi 3']

您不应该使用新阵列的原因如下:

var Array = function () {};

var x = new Array(4);

alert(x.length);  // undefined...

其他一些代码可能会干扰Array变量。我知道任何人都会写这样的代码有点牵强,但是。。。

此外,正如Felix King所说,界面有点不一致,可能会导致一些非常难以追踪的bug。

如果您想要一个长度=x的数组,并填充未定义的(就像新的array(x)那样),您可以这样做:

var x = 4;
var myArray = [];
myArray[x - 1] = undefined;

alert(myArray.length); // 4

请人们不要放弃你的旧习惯。分配内存一次,然后处理该数组中的条目(与以前一样),与在数组增长时多次分配内存(这是系统在使用其他建议方法时不可避免的做法),两者在速度上存在很大差异。

当然,这些都不重要,除非你想用更大的阵列做些酷的事情。然后它就开始了。

鉴于目前JS中似乎仍然没有设置数组初始容量的选项,我使用以下方法。。。

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);
}

需要权衡:

该方法在第一次调用函数时花费的时间与其他方法一样长,但在以后的调用中花费的时间很少(除非要求更大的数组)。标准阵列永久保留的空间与您所要求的最大阵列一样多。

但如果它与你正在做的事情相吻合,就会有回报。非正式计时看跌期权

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

以相当快的速度(假设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倍)。这不仅仅是分配,还有10000次推送、for循环等。。