一尘不染

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

spring

我在JavaScript数组上读过都建通过使用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对其行为的解释之后,看起来jsLint并不真正喜欢new Array()语法,而是[]在声明数组时更喜欢。

所以我有几个问题:

首先,为什么?我使用new Array()语法代替会冒任何风险吗?我应该注意浏览器的不兼容性吗?

其次,如果我切换到方括号语法,是否有任何方法可以声明一个数组并将其长度全部设置在一行上,或者我必须执行以下操作:

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

阅读 1357

收藏
2020-05-02

共3个答案

一尘不染

  • 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]
2022-03-22
一尘不染

  1. 为什么要初始化长度?理论上没有必要这样做。它甚至会导致令人困惑的行为,因为所有使用length来确定数组是否为空的测试都会报告该数组不为空。
    一些 测试表明,如果稍后填充数组,则设置大型数组的初始长度可能更有效,但性能增益(如果有)似乎因浏览器而异。

  2. jsLint 不喜欢new Array(),因为构造函数不明确。

js new Array(4);

创建一个长度为4的空数组。但是

js new Array('4');

创建一个包含 value 的数组'4'

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

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

for(var i = 0; i < length; i++) {
    data.push(createSomeObject());
}
2022-03-22
一尘不染

在现代 JS 引擎中,完全支持稀疏数组。您可以使用[]new Array(len)以任何您喜欢的方式使用,即使是随机访问。字典模式似乎已成为过去。

在当前的 Chrome 中(我猜是任何 V8 环境),数组的长度可以达到 2^32-1 并且分配是稀疏的(这意味着空块不会占用任何内存):

在此处输入图像描述

在此处输入图像描述

但是,有一个问题

一方面,for循环按预期工作,但是,Array内置的高阶函数(例如mapfilterfindsome会忽略未分配的元素。他们首先需要fill(或其他一些人口统计方法):

const a = new Array(10);
const b = new Array(10).fill(0);

a.forEach(x => console.log(x)); // does nothing
b.forEach(x => console.log(x)); // works as intended
2022-03-22