30.JavaScript数组基础、遍历、底层实现、push、pop、at、length

编程之家收集整理的这篇文章主要介绍了30.JavaScript数组基础、遍历、底层实现、push、pop、at、length编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

0b87f80f56636c51322fa0c0cbfe49e5


数组

前面讲到的对象虽然是非常强大的工具,但是,我们在编写代码时常常需要处理一些有序数据的集合。在有序集合中,元素的排列是有前后顺序的,例如:文章的列表、章节目录。由于对象并不能提供属性的有序访问,这种情况下,就需要我们使用新的数据结构数组

数组声明

我们可以通过两种方式创建一个空的数组:

@H_502_76@let arr1 = new Array();//方式1 let arr2 = [];//方式2

由于第二种方式不仅简单,而且直观,我们常常采用第二种方式。

在声明一个数组时,我们可以直接进行初始化:

@H_502_76@let arr = ['Chapter01','Chapter02','Chapter03','Chapter04','Chapter05'];

以上代码创建一个包含五个元素的数组。

元素访问

我们可以通过下标的方式访问数组元素,需要注意的是,数组的编号是从0开始的。

@H_502_76@let arr = ['Chapter01','Chapter05']; console.log(arr[0]);//访问第一个元素,注意下标是0 console.log(arr[3]); console.log(arr[4]);

代码执行结果:

image-20220530103817298

元素替换

通过下标,我们可以直接替换一个数组元素:

@H_502_76@let arr = ['Chapter01','Chapter05']; arr[1] = 'Chapter06';//数组变成了['Chapter01','Chapter06',...]

元素添加

通过下标向数组的末尾添加一个元素:

@H_502_76@let arr = ['Chapter01','Chapter02'] arr[2] = 'Chapter03';//数组变为['Chapter01','Chapter02','Chapter03']

数组长度

通过数组的.length属性可以获得数组中元素的个数

@H_502_76@let arr = ['Chapter01','Chapter02'] console.log(arr.length)//2

循环添加

我们可以利用循环迅速创建一个任意长度的数组,这在我们编程中经常用到:

@H_502_76@let arr = []; for(let i = 0;i < 10;i++){ arr[i] = String(i); }

元素类型

JavaScript数组不限制元素的种类,在同一个数组中可以存储多种类型的数组:

@H_502_76@let arr = [1, '2', { '3' : 3 }];

和对象一样,我们推荐在最后一个元素后添加,,这样在添加元素和移动元素的时候会非常容易:

@H_502_76@let arr = [ 'chapter1', 'chapter2', 'chapter3', ]

at()

访问元素的方法并非一种,我们还可以通过at(IDx)方法访问数组的元素:

@H_502_76@let arr = ['Chapter01','Chapter03']; console.log(arr.at(2));

代码执行效果如下:

image-20220530105722902

以上代码的执行效果使用[IDx]方式完全相同,那么使用at的意义在哪里呢?

最后一个元素

如果我们希望访问数组的最后一个元素,应该怎么办呢?

我们可以使用.length属性实现:

@H_502_76@let arr = ['Chapter01','Chapter03']; console.log(arr[arr.length-1]);

但是这么做非常的不优雅,我们需要写两次数组的名字,此时,我们可以使用at(-1)访问数组的最后一个元素。

@H_502_76@let arr = ['Chapter01','Chapter03']; console.log(arr.at(-1));

同理,访问倒数第二个元素可以使用arr.at(-2)

push、pop、shift、unshift

除了直接使用下标访问数组元素,数组还提供了四个方法用于在数组的首尾添加删除元素:

  1. push:在数组尾部追加一个元素
@H_502_76@let arr = ['First']; arr.push('Second');//此时arr变成了['First','Second']
  1. pop:在数组的尾部取出一个元素,等同于at(-1)
@H_502_76@let arr = ['First','Second','Third']; let last = arr.pop()//等同于arr.at(-1),arr此时为['First','Second'] console.log(last);//Third
  1. shift:从数组头部取出一个元素
@H_502_76@let arr = ['First','Third']; let first = arr.shift();//First,arr变为['First','Second','Third'] console.log(first);
  1. unshift:从数组头部插入一个元素
@H_502_76@let arr = ['Second']; arr.unshift('First');//arr等于['First','Second']

栈是编程中最常用的线性数据结构我们可以使用push/pop方法,把数组当作栈使用

@H_502_76@let st = ['First']; st.push('Second');//压栈 st.pop()//出栈

队列

队列是另外一个常用的线性数据结构我们可以使用push/shift方法,把数组当作队列使用

@H_502_76@let que = ['First']; que.push('Second');//入队 que.shift()//出队

清奇的脑回路

当然,我们可以使用shift/unshift实现栈,通过unshift/pop实现队列,只是通常情况下我们都不这么做~~

遍历

最简单的遍历数组的方式是for循环:

@H_502_76@let arr = ['First','Third']; for(let i = 0;i < arr.length; i++){ console.log(arr[i]) }

代码执行结果:

image-20220530123156573

虽然这么做毫无问题,但是为了更加优雅,我们可以使用for ... of语法:

@H_502_76@let arr = ['First', 'Second', 'Third']; for(let itm of arr){ console.log(itm) }

代码执行结果和上面并无差别:

image-20220530123400977

但是这么做也有一个缺点,就是没有办法获得元素下标,所以我们需要在合适的场景下做合适的选择

length

.length的意义

我们可以使用数组的.length属性获得数组的长度,但是,实际上数组的.length属性并非数组里元素的个数,而是数组最大下标的值加一

@H_502_76@let arr = []; arr[996] = 996; console.log(arr.length)//997

代码的执行结果是不是和想象的不太一样:

image-20220530124006126

我们通常情况下不这么使用数组,所以仍然可以使用.length获取数组的长度。

.length可写

从直观上理解,.length应该是一个可读的属性,实际上,我们是可以修改.length属性的值的:

@H_502_76@let arr = [1,2,3,4,5,] arr.length = 7; console.log(arr.length)//length = 7 console.log(arr[6])//undefined arr.length = 3;//length = 3,数组被截断 arr.length = 5;//length = 5,但是截断的数据不会回来了 console.log(arr.length)//5 console.log(arr[4])//undefined

代码执行结果如下:

image-20220530124743634

修改length会产生如下影响:

  1. 修改后大于当前长度,增长的长度使用undefined填充
  2. 修改后小于当前长度,截断字符串至新长度(截断的部分不可恢复)

Array()

我们使用Array()同样可以创建一个字符串,不过不常用,因为我们更喜欢[]语法。

@H_502_76@let arr = new Array('First','Third');

Array()还有一个不讨喜的特性:当我们使用单个数字参数时,会创建一个指定数字长度的空数组!

如果我们正好要创建一个具有单个数字的数组,就会出错。

@H_502_76@let arr = new Array(4); console.log(arr.length);//4 console.log(arr[3]);//undefined

为了避免出现不必要的错误,还是建议使用[],简单又方便

多维数组

JavaScript的数组同样可以是多维的:

@H_502_76@let arr = [ [1,1,], [2, [3, ]

toString()

数组的toString()方法会把数组元素转为字符串,并以,相隔:

@H_502_76@let arr = [1,3] console.log(arr.toString())//1,2,3 console.log(arr.toString()+1)//1,31

数组比较

数组的本质是一个特殊的对象,因此我们不应该使用==比较两个数组,就像不应该使用==比较对象一样。

  1. 仅当两个数组引用的是同一个对象时,它们才相等;
  2. 如果数组和基础类型比较,将数组转为基础类型后再次比较,转换规则和对象相同对象-基础类型转换;

数组比较:

@H_502_76@console.log([] == [])//false console.log([1] == [1])//false

数组与基础类型比较:

@H_502_76@console.log([] == 0)//true console.log([] == '0')//false console.log([1,3] == "1,3")//true

虽然其中有一定的规律,但是不建议使用==比较数组,我们可以循环逐个比较元素,亦或者使用后面会介绍到的迭代。

数组的本质

数组是一个特殊的对象,方括号加下标的访问方式arr[3]实际上就是对象的属性访问语法obj[key]

数组是对象的扩展,一个属性有序,而且具有length属性的特殊对象,但是本质上仍然是对象。

我们在最初的文章中曾介绍JavaScript共有8中数据类型,数组属于对象范畴。

如何验证数组是一个对象的本质呢?

实验一,数组变量存储的是引用:

@H_502_76@let arr = [1,3] let arr2 = arr; console.log(arr2 === arr);//true arr2.push(4) console.log(arr.toString())//1,3,4

实验二,给数组添加属性

@H_502_76@let arr = [1,3] arr.name = 'arr';

代码执行效果

image-20220530143914801

但是这么做就会破坏数组的特性,将数组变成一个普通的对象。

错误的数组使用

  1. 添加非数字属性,例如arr['name']='xiaoming'
  2. 越界存储,例如在长为3的数组上使用arr[1000]=999
  3. 倒序填充数组,例如arr[1000]=1000arr[999]=999

如果我们不能把数组当作一个有序的数据结构,可以优先考虑对象。

性能

在数组的末端插入数据比数组的头部插入数据要快,也就是push/pop速度比shift/unshift要快。

这是因为,从数组头部移除数据后,引擎会做三件事:

  1. 移除下标为0的值;
  2. 将所有元素像前移动;
  3. 更新length;

数组里面的元素越多,耗费时间越长,push/pop操作在末尾,不会移动任何元素,所以速度很快。

总结

  1. 数组是一个特殊的对象,其元素有序排列,使用下标访问数组元素

  2. 两种声明方式:[]new Array()

  3. at(-1)倒序访问元素

  4. push/pop/shift/unshift操作数组两端的元素

  5. 把数组用作栈、队列

  6. 数组元素遍历forfor offor in(不要使用这个)

  7. 不要使用==比较数组


在这里插入图片描述

解锁查看全部内容

付费后查看完整内容
限时 微信扫码支付 ¥9.9 19.9

总结

以上是编程之家为你收集整理的30.JavaScript数组基础、遍历、底层实现、push、pop、at、length全部内容,希望文章能够帮你解决30.JavaScript数组基础、遍历、底层实现、push、pop、at、length所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

JavaScript相关文章

将npm升级到最新版本即可【】npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
其实从填写上url按下回车后,我们就进入了第一步就是 DNS 解析过程,首先需要找到这个 url 域名的服务器 ip,为了寻找这个 ip,浏览器首先会寻找缓存,查看缓存中是否有记录缓存中没有则查找系统的 hosts 文件中是否有记录,如果没有缓存则查询 DNS 服务器,得到服务器的 ip 地址后,浏览器根据这个 ip 以及相应的端口号发送连接请求;当然如果DNS服务器中没有解析成功,他会向上一步获得的顶级DNS服务器发送解析请求。客户端和服务端都需要直到各自可收发,因此需要三次握手。............
没想到项目放到线上后,随着请求量的增多,却感觉到首屏速度越来越慢,并且是在持续性地变慢。而且在发布完后(也就是容器重建了),耗时又陡然降下来了。因此很合理地怀疑是内存泄漏了。故而在 STKE 的监控面板瞧一瞧,内存确实是一波一波似浪花。知道是内存泄漏,我们就需要找到泄漏的点。因为不能轻易操作线上环境,线上代码也是压缩的,因此我们需要先搭建本地环境看能否方便调试问题。这里我们我们可以在本地起 Server 后,写脚本发起请求,来模拟线上环境。(但是看过上篇文章的小伙伴都知道,我们还有个骨架屏的模式,可以跳过发
文章目录数组数组声明at()push、pop、shift、unshift栈队列遍历length.length的意义.length可写Array()多维数组toString()数组比较数组的本质错误的数组使用性能总结数组前面讲到的对象虽然是非常强大的工具,但是,我们在编写代码时常常需要处理一些有序数据的集合。在有序集合中,元素的排列是有前后顺序的,例如:文章的列表、章节目录。由于对象并不能提供属性的有序访问,这种情况下,就需要我们使用新的数据结构数组。数组声明我们可以通过两种方式创建一个空的数组:.
之前喜欢收集能美化网页的代码,比如给网页加个背景啦,给鼠标加个特效啦,来来回回也收集到了一些“使用简单”,“效果爆炸”的页面,给大家陆续分享出来,如果觉得有帮助可以点赞收藏支持一下,如果能关注一下就再好不过了ヾ(≧▽≦*)o
本网站包含图标库、矢量插画库、3D插画库以及Lottie库,内容丰富且精美,只有你想不到的,没有你找不到的。拿这些精美图标来设计网页页面,一定会惊艳别人。✨美叶  .
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注