我在JavaScript中使用数组读取的大多数教程(包括w3schools和devguru)都建议您可以使用 var test = new Array(4);
语法将整数传递给Array构造函数来初始化具有一定长度的数组 .
在我的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;
16 回答
这是另一种解决方案
apply()
的第一个参数是一个这个对象绑定,我们在这里并不关心,因此我们将其设置为null
.Array.apply(..)
正在调用Array(..)
函数并将{ length: 3 }
对象值展开为其参数 .我很惊讶没有建议的功能解决方案允许您在一行中设置长度 . 以下是基于UnderscoreJS:
由于上面提到的原因,除非我想将数组初始化为特定值,否则我将避免这样做 . 值得注意的是,还有其他库实现了包括Lo-dash和Lazy在内的范围,它们可能具有不同的性能特征 .
使用ES2015 .fill(),您现在可以简单地执行:
哪个比
Array.apply(0, new Array(n)).map(i => value)
简洁得多可以在
.fill()
中删除0
并在不带参数的情况下运行,这将使用undefined
填充数组 . (但是,这将在Typescript中失败)要么
要么
(打字稿安全)
创建嵌套数组
直观地使用
fill
创建 2D 数组时应创建新实例 . 但实际发生的是同一个数组将被存储为参考 .解
所以3x2阵列看起来像这样:
您可以使用
array.length = youValue
设置数组长度所以它会
此代码演示了您不应使用
new Array
的原因:其他一些代码可能会搞乱Array变量 . 我知道任何人都会编写这样的代码有点牵强,但仍然......
此外,正如Felix King所说,界面有点不一致,并且可能导致一些非常难以追踪的错误 .
如果你想要一个长度= x的数组,填充未定义(如
new Array(x)
那样),你可以这样做:ES6引入了Array.from,它允许您从任何 "array-like" 或 iterables 对象创建
Array
:在这种情况下,
{length: 10}
表示 "array-like" 对象的最小定义:仅定义了length
属性的空对象 .Array.from允许第二个参数映射结果数组 .
这会将length属性初始化为4:
最短的:
(作为评论,这可能更好,但是太长了)
因此,在阅读本文之后,我很好奇预分配实际上是否更快,因为理论上它应该是 . 但是,这个博客提供了一些建议反对它http://www.html5rocks.com/en/tutorials/speed/v8/ .
所以仍然不确定,我把它做了测试 . 事实证明它似乎实际上更慢 .
经过几次临时运行后,此代码产生以下结果:
为什么要初始化长度?从理论上讲,没有必要这样做 . 它甚至可能导致令人困惑的行为,因为所有使用
length
来查明数组是否为空的测试都会报告该数组不为空 .Some tests表明如果之后填充数组,设置大型数组的初始长度会更有效,但性能增益(如果有的话)似乎因浏览器而异 .
jsLint不喜欢
new Array()
因为构造函数不明确 .创建一个空数组 of length 4.但是
创建一个数组 containing the value
'4'
.关于你的评论:在JS中,你不需要初始化数组的长度 . 它动态增长 . 您可以将长度存储在某个变量中,例如
数组构造函数有一个ambiguous syntax,而JSLint毕竟只会伤害你的感情 .
此外,您的示例代码已损坏,第二个
var
语句将引发一个SyntaxError
. 您正在设置数组test
的属性length
,因此不需要另一个var
.至于你的选择,
array.length
是唯一的"clean" . 问题是,为什么你需要首先设置尺寸?尝试重构您的代码以摆脱这种依赖 .请人们不要放弃你的旧习惯 . 分配内存一次然后使用该数组中的条目(从旧)开始,并且随着数组的增长分配多次(这不可避免地是系统在其他建议的方法下做的事情)之间的速度差异很大 .
当然,这些都不重要,直到你想用更大的数组做一些很酷的事情 . 然后呢 .
看来目前在JS中似乎没有选项来设置阵列的初始容量,我使用以下内容......
需要权衡:
此方法与第一次调用函数的时间相同,但后续调用的时间非常短(除非要求更大的数组) .
standard
数组会永久保留与您要求的最大数组一样多的空间 .但如果它与你正在做的事情相符,那么就可以获得回报 . 非正式时机提出
非常快速(10000左右,大约50毫秒,n = 1000000,花了大约5秒),和
超过一分钟(相同的镀铬控制台上的10000大约90秒,或慢大约2000倍) . 这不仅仅是分配,还有10000次推送,for循环等 .
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]
如上所述,使用
new Array(size)
有点危险 . 而不是直接使用它,将其放在"array creator function"内 . 您可以轻松确保此功能没有错误,并避免直接调用new Array(size)
的危险 . 此外,您可以为其提供可选的默认初始值 . 这个createArray
函数就是这样做的: