四个初始化 JavaScript Array数组方法及性能对比

在 JavaScript 中初始化数组是常见的场景,初始化有多种方法,创建性能也有差异。虽然可能没有一个放之四海而皆准的解决方案,但是有一些选项您可能需要考虑。

一、Array() 构造函数

首先想到的就是 Array ()构造函数,与直觉相反,这可能是最有问题的初始化数组方法。虽然它适用于任意数量的参数来创建具有给定值的数组,但是在其他任何地方它都不能满足要求。

const arr = Array(3); // [ , , ] - 3个空槽
arr.map(() => 1); // [ , , ] - map() 会跳过空槽
arr.map((_, i) => i); // [ , , ] - map() 会跳过空槽
arr[0]; // undefined - 实际上是一个空槽

注意:

  • 调用 Array() 时可以使用或不使用 new。两者都会创建一个新的 Array 实例。
  • Array 构造函数传入数字来创建指定长度的数组,但存在填充结果均为空槽 undefined,而且在使用map时会直接跳过空槽。

二、Array.from()

Array.from()是一个静态方法,它从类数组对象(带有 length 属性和索引元素的对象)或可迭代对象(例如 Map 和 Set 对象)创建一个新的浅拷贝 Array 实例。

const arr = Array.from({ length: 3 }); // [undefined, undefined, undefined]
arr.map(() => 1); // [1, 1, 1]
arr.map((_, i) => i); // [0, 1, 2]
const staticArr = Array.from({ length: 3 }, () => 1); // [1, 1, 1]
const indexArr = Array.from({ length: 3 }, (_, i) => i); // [0, 1, 2]

Array.from('foo');  // ["f", "o", "o"]

注意:

  • Array.from()对于将类数组对象(例如参数、 NodeList)或迭代器(例如 Set、 Map、 Generator)转换为实际数组非常有用;
  • Array.from()可通过传递一个具有 length 属性的对象,它可以当做类数组对象,“欺骗”它来创建一个给定长度的数组。这有点慢,但能避免 Array () 构造函数空槽会被map跳过的问题;
  • Array.from()允许将映射函数作为第二个参数传递,对于使用值初始化数组非常有用。

三、Array.prototype.fill()

虽然 Array.from ()非常灵活,但是使用映射函数将其填充为相同的值并不特别高效。Array.prototype.fill()允许使用相同的值填充现有数组,可以与 Array ()构造函数一起使用,避免直接用空槽填充数组。

const nullArr = new Array(3).fill(null); // [null, null, null]
const staticArr = Array.from({ length: 3 }).fill(1); // [1, 1, 1]
const indexArr = Array(3).fill(null).map((_, i) => i); // [0, 1, 2]

四、Array.prototype.map()

Array.from()允许通过第二个参数实现映射函数,但很多人认为这很难读懂。此外,还有一些边缘情况:在映射期间如何希望能够访问数组本身的话,可以使用 Map() 灵活处理;但是要注意,map 不能很好地处理空值。

const arr = Array(3).map(() => 1); // [ , , ] - map() skips empty slots
const staticArr = Array.from({ length: 3 }).map(() => 1); // [1, 1, 1]
const indexArr = Array.from({ length: 3 }).map((_, i) => i); // [0, 1, 2]
const fractionArr =
  Array.from({ length: 3 }).map((_, i, a) => i / a.length); // [0, 0.5, 1]

性能总结

如果这种操作在您的应用程序中非常常见,那么性能可能是一个问题,但是总的来说,这些选项都不是特别慢。Array ()构造函数似乎是最快的。如果与 Array.Prototype.fill ()组合,它可能是用单个值初始化数组的最佳选择。奇怪的是,即使随后链接 Array.Prototype.map ()调用以创建动态值,这种性能优势仍然存在。因此推荐的最佳使用方法如下:

// 单个值初始化数组
const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
// 动态值初始化数组
const initializeMappedArray = (n, mapFn = (_, i) => i) =>
  Array(n).fill(null).map(mapFn);

initializeArrayWithValues(4, 2); // [2, 2, 2, 2]
initializeMappedArray(4, (_, i) => i * 2); // [0, 2, 4, 6]

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/89703.html

(0)
guozi's avatarguozi
上一篇 2024年6月4日 下午7:52
下一篇 2024年6月5日 上午10:04

相关推荐

  • 外贸仿牌虚拟主机购买价格是多少钱

    近年来,随着网络行业的不断发展,外贸仿牌虚拟主机的购买需求也日益增加。但是对于很多人来说,外贸仿牌虚拟主机仍然是一个陌生的概念。那么什么是外贸仿牌虚拟主机?它又有哪些特点和优势?更…

    行业资讯 2024年3月20日
    0
  • openwrt dns防污染,openwrt dns插件

    您是否遇到过无法访问特定网站的情况?或者您在浏览网页时是否看到各种广告弹出窗口?这些可能是由DNS 污染引起的。那么什么是DNS污染呢?今天给大家介绍一个简单有效的方法,在open…

    行业资讯 2024年5月12日
    0
  • 在公司屏蔽网络违法吗,公司屏蔽网站怎么破

    当一个公司的网站被屏蔽时,搜索引擎将无法访问和收录该网站的内容,从而影响该网站在搜索引擎上的排名。如果长时间被屏蔽,您的网站可能会从搜索结果中消失,从而影响您的品牌曝光和客户获取。…

    行业资讯 2024年5月11日
    0
  • 备案号的作用是什么?

    备案号,这个在网络行业中广为人知的名词,你是否真正了解它的作用是什么?它是如何产生的?备案号又有着怎样的申请流程?更重要的是,备案号对于我们来说又有着怎样的意义呢?如果你还没有完全…

    行业资讯 2024年3月20日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注