学习Array类型看这一篇就够了(Array类型特点,Array原型方法,浏览器sort底层实现,深浅拷贝)

简介: 学习Array类型看这一篇就够了(Array类型特点,Array原型方法,浏览器sort底层实现,深浅拷贝)

除了Object之外,Array类型应该是ECMAScript中常用的类型,并且javaScript中的Array类型和其他语言中的数组非常的不同,本文将由浅入深地从 创建Array类型原型方法两个大方向带大家彻底理解这个ECMAScript中的重要类型



一、创建Array类型

1.1 创建数组

   创建数组有两种基本方式,第一种是使用Array构造函数

640.png

   第二种是数组字面量表示法,由一对包含数组项的方括号表示,多个数组之间以逗号隔开。


640.png


1.2 不限制类型

   javaScript中的Array类型和其他语言一样都是数据的有序列表,但是因为javaScript是弱类型语言的关系,与其他语言不同的是,javaScript的每一项数组元素可以存放任何类型的数据640.png


   可以看到Array数组可以包容任何类型的数据

1.3 数组length

   javaScript的数组大小也与其他语言有不尽相同的地方,javaScript的Array类型是支持动态调整的,即可以随着数据的添加自动增长以容纳新的元素,与别的语言相同,Array类型同样也是用length来访问数组的长度大小。

640.png

   同时,数组的length属性很有特点—它不只是只读的,因此通过这个属性,是可以从数组的末尾移除项或者添加项的

640.png


二、原型方法

2.1 转换方法

   Array类型在原型处封装了三个方法用于数组转换,values(),toString(), toLocaleString()。

values()返回的包含数组所有元素的一个新的Iteractor对象(不知道Iteractor对象的同学可以Bing一下,或者看我后面写的关于Iteractor对象的文章)
toString()返回的是数组每个值的字符串形式并用一个逗号分隔拼接而成的字符串
toLocaleString()和toString()结果相似,不过是返回的是方法下的toLocaleStrng()方法640.png640.png


   可以看到toString()和toLocaleString()方法是调用了数组元素对应的方法来把返回值拼接起来的,而values()返回的迭代器对象遍历出来正好就是数组的每个元素

2.2 数据添加移除方法

   javaScript提供了让数组实现栈和队列的方法,栈是一种先进后出的数据结构,即最新添加的项目最早被移除,队列是一种先进先出的数据结构,最新添加的项目最晚被移除

push():向数组末尾添加元素
pop():移除数组末尾的元素
shift():移除数组前端的元素
unshift():向数组前端添加元素

   使用push()和pop()就可以像栈一样使用数组,使用shift()和push()方法,就可以像队列一样使用数组

640.png


2.3 重排序方法

640.png

   Array类型提供了reverse()方法和sort()方法用于数组的重排序,reverse()方法用于反转对应的数组,sort()方法将按对应的排序方式进行排序,默认采用升序的排序, 当然也可以自己定义compare方法来定义排序的方式
   与C++等语言compare不同的是,js的compare方法不能支持对bool值的返回,也就是说类似下面写法的compare方法没办法进行排序

640.png

   js比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相同返回0,如果第一个参数应该位于第二个之后则返回一个正数

640.png

   这里提供了一个降序排序的写法,大家可以结合代码自己实现一下。

2.4 sort方法底层实现的算法

   ECMAScript 不同版本规范对 Array.prototype.sort 的定义中没有要求用什么样的排序方式实现 sort() 方法,也没有要求是否要采用稳定排序算法
因此各浏览器都给出自己的实现方式:

   表格内容部分来自于维基百科

浏览器 使用的 JavaScript 引擎 排序算法
Google Chrome V8 插入排序和快速排序
Mozilla Firefox SpiderMonkey 归并排序
Safari Nitro(JavaScriptCore ) 归并排序和桶排序
Microsoft Edge 和 IE(9+) Chakra 快速排序

   下面是相关算法的时间复杂度

排序类型 平均情况 最好情况 最坏情况 辅助空间 稳定性
快速排序 O(nlogn) O(nlogn) O(n²) O(nlogn) 不稳定
归并排序 O(nlogn) O(nlogn) O(nlogn) O(nlogn) 稳定
插入排序 O(n²) O(n) O(n²) O(1) 稳定
桶排序 O(n+k) O(n+k) O(n²) O(n+k) (不)稳定

   辅助空间大家可以理解成是算法执行过程中所需要的空间,O(1)是最理想的, 因为这样的算法其辅助空间不依赖于问题的规模,换句话说这样的算法是稳定的。
大家可以看到,各个浏览器对sort的底层实现方式都是不同的,这里也可以看到IE所使用的快排在最坏的情况是可以达到O(n^2)的复杂度的,这里给出一张不同复杂度排序算法在不同的数据量下的响应时间表帮助大家理解我下面将要谈到的问题

640.png

   不难看到,当数据量达到10W以后,O(n^2)的排序方法是需要3-4min的,对于的网页渲染肯定是及其不好的,所以我们其实可以知道,用原生的sort方法,不同浏览器的实现不同,意味着会有性能上的不同和兼容性,尤其在面对大数量的数据面前,这个问题暴露得尤为明显
   所以,当大家要在前端进行数据的排序处理的时候,要注意数据量会不会导致不同浏览器的渲染效果出现明显差异,如果出现了卡顿或者处理时间过长的问题,自己封装一个稳定的排序函数,以保持各浏览器的一致性。

2.4 操作方法

   这一小节要和大家介绍的是Array类型最常用的三个操作方法:concat(),slice(),splice()

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
----《MDN web docs》

   上面三个方法除了splice方法以外都是返回一个新的数组对象,而不会对原始数组改变,concat方法起一个合并数组的作用,slice方法是对数组的一个浅拷贝(具体什么是浅拷贝将在下一小节具体说明),而splice方法的功能最为强大,可以删除,可以增添,也可以替换数组的元素。splice方法有三个参数,第一个参数是操作的起始位置,第二个是删除元素的个数,如果是0,就不进行删除操作,第三个参数可以有多个,是要添加进数组的元素,会从第一个参数的起始位置开始添加。


640.png


2.5 浅拷贝和深拷贝

   深拷贝和浅拷贝只针对Object和Array这样的引用数据类型。
   具体到底应该怎么区分浅拷贝和深拷贝呢?
   简单来说,就是假设B复制了A,为修改A时,看B是否会变化,如果B也跟着变了,说明这是浅拷贝,拿人手短。如果B没变。那就是深拷贝,自食其力

2.6 其他方法

   Array类型其他的方法,并不是说这些方法不重要,只是ES6中已经有了对于下面方法很好的替代,所以这里就不再对这些方法做具体的解释了,如果感兴趣的同学可以到MDN上查阅相关的方法
   进入MDN查阅更多Array类型原型方法

三、总结

      1、Array类型支持在一个数组对象中包含不同的数据类型
      2、Array类型支持内存的动态调整,并且length属性不只是一个只读对象,通过调整这个属性甚至可以对数组对象进行增删的操作
      3、Array类型实现了像栈和队列的数据结构的操作,使用push()和pop()可以像栈一样使用数组,使用shift()和push()可以像队列一样使用数组
      4、sort方法支持自定义compare方法进行排序,不支持对bool型的返回,只支持对数字的返回
      5、sort方法在不同浏览器中的底层实现方式和算法复杂度都不同,可能出现浏览器渲染效率有差异和数据量巨大情况下浏览器卡顿的情况,要解决这个问题,需要不在前端进行数据的排序,或者自己写一个稳定的排序函数来统一原生的sort方法。

   小伙伴们今天的学习就到这里了,如果觉得本文对你有帮助的话,欢迎转发,评论,收藏,点赞!!!

目录
相关文章
|
1月前
|
前端开发 JavaScript
前端 js 经典:array 原生方法
前端 js 经典:array 原生方法
24 1
|
1月前
|
JavaScript 前端开发 索引
JavaScript array 原生 reduce 方法的模拟实现
JavaScript array 原生 reduce 方法的模拟实现
|
1月前
实现array.slice()方法
实现array.slice()方法
|
1月前
|
Web App开发 测试技术 Python
【如何学习python自动化测试】—— 浏览器驱动的安装 以及 如何更新driver
【如何学习python自动化测试】—— 浏览器驱动的安装 以及 如何更新driver
31 0
|
1月前
|
编解码 测试技术 Python
【如何学习Python自动化测试】—— 浏览器操作
【如何学习Python自动化测试】—— 浏览器操作
13 0
|
1月前
|
Rust 索引 Windows
Rust 原始类型之数组array内置方法
Rust 原始类型之数组array内置方法
89 0
Rust 原始类型之数组array内置方法
|
1月前
|
存储 JavaScript 索引
TypeScript 中的 Array 类型是什么样的?
TypeScript 中的 Array 类型是什么样的?
67 1
|
1月前
|
SQL IDE Java
MyBatis【问题 01】mapper传入array\collection\list类型的参数时报BindingException:Parameter ‘xx‘ not found问题复现及解决
MyBatis【问题 01】mapper传入array\collection\list类型的参数时报BindingException:Parameter ‘xx‘ not found问题复现及解决
88 0
|
1月前
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]
ES6的Array.from({length:N})方法创建长度为N的undefined数组,等价于 [...Array(N)]
|
1月前
|
存储
【Vue2.0学习】—浏览器本地存储(五十七)
【Vue2.0学习】—浏览器本地存储(五十七)