我在JavaScript中使用数组(包括w3schools和devguru)阅读的大多数教程都建议您可以通过将整数传递给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's explanation of its behavior后,看起来jsLint并不真正喜欢new Array()
语法,而是在声明数组时更喜欢[]
。
所以我有几个问题。首先,为什么?我是否因使用new Array()
语法而冒任何风险?是否存在我应该注意的浏览器不兼容性?第二,如果我切换到方括号语法,有没有办法声明一个数组并在一行上设置它的长度,或者我必须做这样的事情:
var test = [];
test.length = 4;
答案 0 :(得分:429)
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)
如果你想用一定的价值进行初始化,这些都很有用......
Array.from('abcde')
,Array.from('x'.repeat(5))
或Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
答案 1 :(得分:325)
为什么要初始化长度?从理论上讲,没有必要这样做。它甚至可能导致混淆行为,因为所有使用length
来确定数组是否为空的测试都会报告该数组不为空。
Some tests表示如果之后填充数组,设置大型数组的初始长度会更有效,但性能增益(如果有的话)似乎与浏览器不同浏览器。
jsLint不喜欢new Array()
,因为构造函数不明确。
new Array(4);
创建一个长度为的空数组 4.但是
new Array('4');
创建一个包含值 '4'
的数组。
关于你的评论:在JS中,你不需要初始化数组的长度。它动态增长。您可以将长度存储在某个变量中,例如
var data = [];
var length = 5; // user defined length
for(var i = 0; i < length; i++) {
data.push(createSomeObject());
}
答案 2 :(得分:188)
使用ES2015 .fill()
,您现在可以执行以下操作:
// `n` is the size you want to initialize your array
// `0` is what the array will be filled with (can be any other value)
Array(n).fill(0)
比Array.apply(0, new Array(n)).map(i => value)
可以将0
放入.fill()
并运行不带参数,这将使数组填充undefined
。 (但是,这将在Typescript中失败)
答案 3 :(得分:53)
最短的:
[...Array(1000)]
答案 4 :(得分:33)
ES6引入Array.from
,可让您从任何“类似数组”或 iterables 对象创建Array
:
Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在这种情况下,{length: 10}
表示“类似数组”对象的最小定义:一个只定义了length
属性的空对象。
Array.from
允许第二个参数映射结果数组。
答案 5 :(得分:32)
[...Array(6)].map(x=>0);
// [0, 0, 0, 0, 0, 0]
或
Array(6).fill(0);
// [0, 0, 0, 0, 0, 0]
注意:您无法循环空广告位Array(4).forEach( (_,i) => {} )
或
Array(6).fill(null).map( (x,i) => i );
// [0, 1, 2, 3, 4, 5]
( typescript safe )
直观地创建带有fill
的 2D 数组时,应创建新实例。但实际发生的事情是将相同的数组存储为参考。
var a = Array(3).fill([6]);
// [[6], [6], [6]]
a[ 0 ].push( 9 );
// [[6,9], [6,9], [6,9]]
解决方案
var a = [...Array(3)].map(x=>[]);
a[ 0 ].push( 4, 2 );
// [[4,2], [ ], [ ]]
所以3x2数组看起来像这样:
[...Array(3)].map(x=>Array(2).fill(0));
// [ [0,0] ,
// [0,0] ,
// [0,0] ]
答案 6 :(得分:25)
这会将length属性初始化为4:
var x = [,,,,];
答案 7 :(得分:16)
我很惊讶没有建议的功能性解决方案允许您将长度设置为一行。以下是基于UnderscoreJS:
var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);
由于上述原因,除非我想将数组初始化为特定值,否则我将避免这样做。值得注意的是,还有其他库可以实现范围,包括Lo-dash和Lazy,它们可能具有不同的性能特征。
答案 8 :(得分:8)
(作为评论可能更好,但是太长了)
因此,在阅读本文后,我很好奇预分配实际上是否更快,因为理论上它应该是。但是,这个博客提供了一些建议反对它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
答案 9 :(得分:7)
var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6
答案 10 :(得分:7)
请人们不要放弃你的旧习惯。 分配内存一次然后处理该阵列中的条目(从旧)开始,并在阵列增长时分配多次(这不可避免地是系统在其他建议的方法下做的事情)之间的速度差异很大
当然,除非你想用更大的数组做一些很酷的事情,否则这一切都不重要。然后呢。
看来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);
}
涉及权衡:
standard
数组会永久保留与您要求的最大数组一样多的空间。但如果它符合您所做的事情,那么可能会有回报。 非正式时间安排
for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}
速度非常快(10000左右,大约50毫秒,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循环等等。
答案 11 :(得分:6)
这是另一种解决方案
var arr = Array.apply( null, { length: 4 } );
arr; // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4
apply()
的第一个参数是一个这个对象绑定,我们在这里并不关心,因此我们将其设置为null
。
Array.apply(..)
正在调用Array(..)
函数并将{ length: 3 }
对象值作为其参数展开。
答案 12 :(得分:3)
数组构造函数有一个ambiguous syntax,而JSLint毕竟只会伤害你的感情。
此外,您的示例代码已损坏,第二个var
语句将引发SyntaxError
。您正在设置数组length
的属性test
,因此不需要其他var
。
就你的选择而言,array.length
是唯一的“干净”选择。问题是,为什么你需要首先设置尺寸?尝试重构您的代码以摆脱该依赖。
答案 13 :(得分:2)
假定数组的长度是恒定的。在Javascript中,这是我们要做的:
const intialArray = new Array(specify the value);
答案 14 :(得分:1)
如上所述,使用new Array(size)
有点危险。而不是直接使用它,将其放在“数组创建器函数”中。您可以轻松确保此功能没有错误,并避免直接调用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;
}
答案 15 :(得分:0)
在大多数答案中,建议使用fill
数组,否则“您无法对其进行迭代” ,但这不是事实。您可以迭代一个空数组,而不能使用forEach
进行迭代。 While循环,for循环和for i循环工作正常。
const count = Array(5);
不起作用。
console.log('---for each loop:---');
count.forEach((empty, index) => {
console.log(`counting ${index}`);
});
这些作品:
console.log('---for of loop:---');
for (let [index, empty] of count.entries()) {
console.log(`counting for of loop ${index}`);
}
console.log('---for i loop:---');
for (let i = 0, il = count.length; i < il; ++i) {
console.log(`counting for i loop ${i}`);
}
console.log('---while loop:---');
let index = 0;
while (index < count.length) {
console.log(`counting while loop ${index}`);
index++;
}
通过上述示例检查 this fiddle 。
角度*ngFor
也可以与空数组配合使用:
<li *ngFor="let empty of count; let i = index" [ngClass]="
<span>Counting with *ngFor {{i}}</span>
</li>
答案 16 :(得分:-1)
您可以使用array.length = youValue
所以它会是
var myArray = [];
myArray.length = yourValue;
答案 17 :(得分:-1)
此代码演示了您不应使用new Array
的原因:
var Array = function () {};
var x = new Array(4);
alert(x.length); // undefined...
其他一些代码可以搞乱Array变量。我知道任何人都会写这样的代码有点牵强,但仍然......
另外,正如Felix King所说,界面有点不一致,可能会导致一些非常难以追踪的错误。
如果你想要一个长度为x的数组,填充未定义(如new Array(x)
那样),你可以这样做:
var x = 4;
var myArray = [];
myArray[x - 1] = undefined;
alert(myArray.length); // 4