返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript稀疏数组与孔hole示例详解
  • 559
分享到

JavaScript稀疏数组与孔hole示例详解

2024-04-02 19:04:59 559人浏览 泡泡鱼
摘要

目录稀疏数组是什么javascript数组天生就是稀疏数组JavaScript数组稀疏特性带来的“怪异现象”slice会复制孔forEach、every会跳过

稀疏数组是什么

在绝大多数JavaScript的实现中,数组是稀疏的,我们可以认为js的数组都是稀疏的(虽然ES标准并没有这样规定)。

稀疏数组与密集数组最大的不同,就是稀疏数组中可以有“孔”(hole)。孔是逻辑上存在于数组中,但物理上不存在与内存中的那些数组项。在那些仅有少部分项被使用的数组中,孔可以大大减少内存空间的浪费。比如,我们要表示一个长度为10000的数组,它的最后一个项是字符串'a'。如果按照密集数组的做法,我们需要开辟10000个项的空间,有9999个项的空间都被浪费了。而如果按照稀疏数组的做法,稀疏数组只需要记录:“数组第10000个项的值为'a'”,这节省了很多内存空间。

JavaScript数组天生就是稀疏数组

js数组就是若干个下标(数字)与值之间的映射。从下标x到值y的映射表示:“数组第x个项的值为y”。这实际上就是上例中稀疏数组的记录方法。

在Chrome控制台的执行结果


如上图,如果你调用new Array(3),你得到的数组中只有一个属性length,记录了它的长度,但是没有任何下标(数字)与值之间的映射。这是一个只有3个孔的数组。

如上图,如果你继续执行a[1] = 'aaa',那么实际上是在这个稀疏数组中增加了一条从1到"aaa"之间的映射。

如上图,如果你继续执行a[10000]='bbb',也只不过是又增加了一条从10000到"bbb"之间的映射而已。length自动变为了10001,这符合我们的直觉。不存在映射关系,但又处在数组长度范围内的数组项,就是孔。此时,这个数组与长度为2的普通数组['aaa', 'bbb'],占用相同大小的内存空间。

JavaScript数组稀疏特性带来的“怪异现象”

slice会复制孔

var arr = [ 'a', , 'b' ]
// ["a", undefined × 1, "b"]
arr.slice(1,2)
// [undefined × 1]
arr.slice()
// ["a", undefined × 1, "b"]

forEach、every会跳过孔(不对孔调用回调函数)

var arr = [ 'a', , 'b' ]
// ["a", undefined × 1, "b"]
arr.forEach(function (x, i) { console.log(i+'.'+x) })
// 0.a
// 2.b
arr.every(function (x) { return x.length === 1 })
// true

map不对孔调用回调函数,但是孔会保留

arr.map(function (x,i) { return i+'.'+x })
// [ '0.a', undefined × 1, '2.b' ]

filter不对孔调用回调函数,但是孔会被过滤掉

arr.filter(function (x) { return true })
// [ 'a', 'b' ]

join会将孔转化为一个空字符串进行拼接,与undefined一样

arr.join('-')
// 'a--b'
[ 'a', undefined, 'b' ].join('-')
// 'a--b'

而其他所有的数组方法会正常对待孔,就像数组中真的存在这个“空位”一样:

var arr2 = arr.slice()
arr2.sort()
// [ 'a', 'b', undefined × 1 ]

初始化无孔数组的方法

因为数组中的孔会造成上述的那些“怪异现象”,所以我们有时希望初始化一个没有孔的数组。
比如我们希望初始化[0,1,2]这样的数组,但是我们无法通过new Array(3)与map方法得到:

var a1 = new Array(3)
// [undefined × 3]
a1.map(function (x, i) { return i })
// [undefined × 3]
// 因为map会跳过孔,所以实际上回调函数没有被调用过

a1有孔

正确的方法:

var a2 = Array.apply(null, Array(3))
// [undefined, undefined, undefined]
a2.map(function (x, i) { return i })
// [0, 1, 2]
// map的回调函数执行了3次

a2无孔

[undefined × 3]和[undefined, undefined, undefined],chrome控制台用这两种表示方式来区分孔和真正的undefined值!

从上面两幅图的对比可以看出,第一种方法没有构造出映射,只创造出了3个孔。而第二种方法创建出了真正的“从下标到值之间的映射”,映射的值为undefined。因此map不会跳过这些数组项。

Array.apply(null, Array(n))的原理

为什么var a2 = Array.apply(null, Array(3))能创造出无孔的数组呢?

我们将一个含有3个孔的数组作为第二个参数传递给apply,apply将利用这个数组来决定调用Array()的参数。

因为apply将数组中的孔视为undefined,所以Array调用的参数实际上为Array(undefined, undefined, undefined)。

又因为通过Array(a,b,c)这种方法调用Array会返回[a,b,c],所以Array(undefined, undefined, undefined)返回的是[undefined, undefined, undefined]。

参考资料

https://2ality.com/2013/11/initializing-arrays.html

Https://2ality.com/2013/07/array-iteration-holes.html

https://2ality.com/2012/06/dense-arrays.html

https://2ality.com/2015/09/holes-arrays-es6.html

以上就是JavaScript稀疏数组与孔hole示例详解的详细内容,更多关于JavaScript稀疏数组与孔hole的资料请关注编程网其它相关文章!

--结束END--

本文标题: JavaScript稀疏数组与孔hole示例详解

本文链接: https://lsjlt.com/news/152733.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript稀疏数组与孔hole示例详解
    目录稀疏数组是什么JavaScript数组天生就是稀疏数组JavaScript数组稀疏特性带来的“怪异现象”slice会复制孔forEach、every会跳过...
    99+
    2024-04-02
  • JavaScript稀疏数组示例教程
    目录前言什么是稀疏数组?创建带有孔洞的稀疏数组删除元素的映射现象稀疏数组的快速映射(强制创建映射关系)总结前言 最近有空在看一本关于 JS 数据结构和算法的书,里面有提到数组,却对数...
    99+
    2024-04-02
  • java数据结构算法稀疏数组示例详解
    目录一、什么是稀疏数组二、场景用法1.二维数组转稀疏数组思路2.稀疏数组转二维数组思路3.代码实现一、什么是稀疏数组 当一个数组a中大部分元素为0,或者为同一个值,那么可以用稀疏数组...
    99+
    2024-04-02
  • java稀疏数组的示例代码
    稀疏组织 当一个数组中大部分元素为0,或者为同一个值的数组时,可以用稀疏数组来保存该数组稀疏数组,记录一共有几行几列,有多少个不同值把具有不同值的元素和行里了及值记录在一个小规模的数...
    99+
    2024-04-02
  • Java二维数组与稀疏数组相互转换实现详解
    目录一、稀疏数组1、什么是稀疏数组2、图示3、稀疏数组的表达方式二、二维数组→稀疏数组三、稀疏数组→二维数组一、稀疏数组 1、什么是稀疏数组 当一个数组中大部分元...
    99+
    2024-04-02
  • Java数据结构实现二维数组与稀疏数组转换详解
    基本介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 稀疏数组的处理方法是: ①记录数组一共有几行几列,有多少个不同的值(0除外)。 ②把具有...
    99+
    2024-04-02
  • golang数据结构之golang稀疏数组sparsearray详解
    目录一、稀疏数组1. 先看一个实际的需求2. 基本介绍3. 应用实例一、稀疏数组 1. 先看一个实际的需求 编写的五子棋程序中,有存盘退出和续上盘的功能 分析按照原始的方式来的二维...
    99+
    2024-04-02
  • Java数据结构与算法之稀疏数组与队列深入理解
    目录一、数据结构和算法简介二、稀疏数组稀疏数组的应用实例二维数组与稀疏数组的转换二维数组 转 稀疏数组的思路稀疏数组 转 原始的二维数组的思路三、队列数组模拟队列代码优化:数组模拟环...
    99+
    2024-04-02
  • JavaScript数组方法实例详解
    目录简介创建数组创建方法详解方法大全join()push()和 pop()shift() 和 unshift()sort()reverse()concat()sl...
    99+
    2024-04-02
  • JavaScript函数封装的示例详解
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g...
    99+
    2024-04-02
  • JavaScript中数组、栈与队列的示例分析
    这篇文章主要介绍了JavaScript中数组、栈与队列的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。...
    99+
    2024-04-02
  • JavaScript箭头函数与普通函数的区别示例详解
    目录箭头函数与普通函数的区别箭头函数的理解箭头函数里的this指向总结箭头函数与普通函数的区别 要讨论箭头函数和普通函数的区别,首先来看看两者的基本格式 普通函数和箭头共同点就是圆...
    99+
    2022-11-13
    JavaScript箭头函数普通函数 JavaScript 箭头普通函数区别
  • PythonNumPy数组索引的示例详解
    目录前言1、访问数组元素2、访问 2-D Arrays(数组)3、访问 3-D Arrays(数组)4、负索引前言 NumPy(Numerical Python的缩写)是一个开源的P...
    99+
    2023-01-18
    Python NumPy 数组索引 Python NumPy 索引 NumPy 数组索引
  • Python内置数据结构列表与元组示例详解
    目录1. 序列 2. 列表 2.1 列表的特性2.1.1 列表的连接操作符和重复操作符 2.1.3 列表的索引 2.1.4 列表的切片 2.1.5 列表的循环(for) 2.2 列表...
    99+
    2024-04-02
  • PHP数组函数详解及实例演示
    PHP数组函数详解及实例演示 在PHP开发中,数组是一种非常重要的数据结构,它可以存储多个值,并通过键值对的方式来访问这些值。PHP提供了许多强大的数组函数,可以帮助我们对数组进行各种...
    99+
    2024-03-13
    函数 php数组 示例 键值对
  • java数据结构与算法数组模拟队列示例详解
    目录一、什么是队列二、用数组来模拟队列一、什么是队列 队列是一个有序列表,可以用数组或者链表来实现。遵循先入先出的原则,即:先存入队列的数据,要先取出。后存入的的数据,后取出。 看一...
    99+
    2024-04-02
  • JavaScript数组reduce()方法使用实例详解
    目录前言1、累加和累积乘法2、获取一个数组的最大值和最小值3、计算数组中元素出现的频率4、多个数组的展平总结前言 今天请让我详细介绍一下这个方法,希望对你有帮助。 这是 reduce...
    99+
    2024-04-02
  • React元素与组件的区别示例详解
    目录从问题出发元素与组件元素组件问题如何解决自定义内容第一种实现方式第二种实现方式第三种实现方式从问题出发 我被问过这样一个问题: 想要实现一个 useTitle 方法,具体使用示例...
    99+
    2022-11-13
    React元素组件区别 React元素组件
  • Java实现差分数组的示例详解
    目录前言应用场景Leetcode题目实战题目描述思路代码前言 昨天(2022-06-07)在做leetcode每日一题的时候,第一次看到了这个超级简单但是很实用的算法---差分数组,...
    99+
    2024-04-02
  • javascript中数组排序与对象排序的示例分析
    这篇文章将为大家详细讲解有关javascript中数组排序与对象排序的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。javascript  数组排序与对...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作