JS数组操作函数包括什么,用法是怎样的
Admin 2022-07-14 群英技术资讯 1264 次浏览
这篇文章将为大家详细讲解有关“JS数组操作函数包括什么,用法是怎样的”的知识,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
上篇介绍了数组的基本概念和一些简单的数组元素操作函数,实际上,数组提供的函数还有很多。
push、pop、shift和unshift是操作数组首尾两端的函数,上文已经讲过,本文不再赘述。
上篇已经简单介绍过,数组就是一个特殊的对象,因此我们可以尝试使用对象的属性删除方法:delete。
举个例子:
let arr = [1,2,3,4,5];delete arr[2];console.log(arr);
代码执行结果如下:

注意观察图中标黄的位置,虽然元素被删除了,但是数组的长度仍然是5,而且删除掉的位置多了一个空。如果我们访问下标为2的元素,会得到如下的结果:

造成这种现象的原因是,delete obj.key是通过key移除对应值的,也就是说delete arr[2]删除了数组中的2:3键值对,当我们访问下标2时,就是undefined了。
而在数组中,我们常常希望删除元素后,元素的位置会被后继的元素填补,数组的长度变短。
这个时候,我们就需要splice()方法。
需要提前说明的是,splice()方法的功能相当丰富,并非只能删除元素,以下是语法:
arr.splice(start[,deleteCount,e1,e2,...,eN])
splice方法从start位置开始,删除deleteCount个元素,然后原地插入e1,e2,e3等元素。
以下实例可以从数组中删除一个元素:
let arr = [1,2,3,4,5]arr.splice(0,1);//删除掉第一个元素1console.log(arr)
以上代码删除数组中第一个位置的1个元素,执行结果如下:

删除多个元素和删除一个元素用法相同,只需要将第二个参数改为指定数量就可以了,举例如下:
let arr = [1,2,3,4,5];arr.splice(0,3);//删除前三个元素console.log(arr);//[4,5]
代码执行结果如下:

如果我们只提供一个参数start,那么就会删除数组start位置后面的所有元素,举个例子:
let arr = [1,2,3,4,5]arr.splice(2);//删除从下标为2以及后面的所有元素console.log(arr);//[1,2]
代码执行结果:

如果我们提供了超过两个参数,那么就可以替换数组元素,举个例子:
let arr = [1,2,3,4,5];arr.splice(0,2,'itm1','itm2','itm3');console.log(arr);//['itm1','itm2','itm3',3,4,5]
代码执行结果如下:

以上代码实际上执行了两步操作,首先删除从0开始的2个元素,然后在0位置插入三个新的元素。
如果我们把第二个参数(删除数量)改为0,那么就可以只插入元素,不删除元素,举个栗子:
let arr = [1,2,3,4,5]arr.splice(0,0,'x','y','z')console.log(arr);//['x','y','z'1,2,3,4,5]

splice()函数会返回被删除的元素数组,举个例子:
let arr = [1,2,3,4,5]let res = arr.splice(0,3,'x','y')console.log(arr)//['x','y',4,5]console.log(res)//[1,2,3]
代码执行结果:

我们可以使用负数指示开始操作元素的位置,举个例子:
let arr = [1,2,3,4,5]arr.splice(-1,1,'x','y','z')console.log(arr)//[1,2,3,4,'x','y','z']
代码执行结果如下:

slice()方法可以截取指定范围的数组,语法如下:
arr.slice([start],[end])
返回一个新数组,新数组从start开始,到end结束,但是不包括end。
举例:
let arr = [1,2,3,4,5]console.log(arr.slice(2,5))//[3,4,5]console.log(arr.slice(1,3))//[2,3]
代码执行结果:

slice()同样可以使用负数下标:
let arr = [1,2,3,4,5]console.log(arr.slice(-3))//[3,4,5]console.log(arr.slice(-5,-1))//[1,2,3,4]
代码执行结果如下:

如果只为slice()方法提供一个参数,就会和splice()一样截断到数组末尾。
concat()函数可以将多个数组或者其他类型的值拼接称一个长数组,语法如下:
arr.concat(e1, e2, e3)
以上代码将返回一个新的数组,新数组由arr拼接e1、e2、e3而成。
举例:
let arr = [1,2,3]console.log(arr.concat([4,5],6,7,[8,9]))
代码执行结果如下:

普通的对象,即使它们看起来和对象一样,仍然会被作为一个整体插入到数组中,例如:
let arr = [1,2]let obj = {1:'1',2:2}console.log(arr.concat(obj))代码执行结果:

但是,如果对象具有Symbol.isConcatSpreadable属性,就会被当作数组处理:
let arr = [1,2]let obj = {0:'x',
1:'y',
[Symbol.isConcatSpreadable]:true,
length:2 }console.log(arr.concat(obj))代码执行结果:

遍历整个数组,为每个数组元素提供一个操作函数,语法:
let arr = [1,2]arr.forEach((itm,idx,array)=>{
...})应用举例:
let arr = [1,2,3,4,5]arr.forEach((itm)=>{
console.log(itm)})代码执行结果:

let arr = [1,2,3,4,5]arr.forEach((itm,idx,array)=>{
console.log(`arr[${idx}] in [${array}] is ${itm}`)})代码执行结果:

类似于字符串,indexOf、lastIndexOf、includes可与查询数组中指定元素的下标:
arr.indexOf(itm,start):从start位置开始搜索itm,如果找到返回下标,否则返回-1;arr.lastIndexOf(itm,start):倒序查找整个数组,直至start处,返回第一个查到的下标(也就是数组最后一个匹配项),找不到返回-1;arr.includes(itm,start):从start位置开始搜索itm,找到返回true,否则返回false;举例:
let arr = [1,2,3,4,5,6,"7","8","9",0,0,true,false]console.log(arr.indexOf(0))//9console.log(arr.lastIndexOf(0))//10console.log(arr.includes(10))//falseconsole.log(arr.includes(9))//false
这些方法在比较数组元素的时候使用的是===,所以false和0是不一样的。
NaN的处理
NaN是一个特殊的数字,三者在处理NaN有细微差别:
let arr = [NaN,1,2,3,NaN]console.log(arr.includes(NaN))//trueconsole.log(arr.indexOf(NaN))//-1console.log(arr.lastIndexOf(NaN))//-1
产生这种结果的原因和NaN本身的特性有关,即NaN不等于任何数字,包括他自己。
这些内容在前面的章节已经讲过了,遗忘的童鞋记得温故知新呀。
在编程过程中常常会遇到对象数组,而对象是不能直接使用===比较的,如何从数组中查找到满足条件的对象呢?
这个时候就要使用find和findIndex方法,语法如下:
let result = arr.find(function(itm,idx,array){
//itm数组元素
//idx元素下标
//array数组本身
//传入一个判断函数,如果该函数返回true,就返回当前对象itm})举个栗子,我们查找name属性等于xiaoming的对象:
let arr =[
{id:1,name:'xiaoming'},
{id:2,name:'xiaohong'},
{id:3,name:'xiaojunn'},]let xiaoming = arr.find(function(itm,idx,array){
if(itm.name == 'xiaoming')return true;})console.log(xiaoming)代码执行结果:

如果没有符合条件的对象,就会返回undefined。
以上代码还可以简化为:
let xiaoming = arr.find((itm)=> itm.name == 'xiaoming')
执行效果是完全相同的。
arr.findIndex(func)的用途和arr.find(func)几乎相同,唯一不同的地方在于,arr.findIndex返回符合条件对象的下标而不对象本身,找不到返回-1。
find和findIndex只能查找一个满足要求的对象,如果一个数组中存在多个满足要求的对象,就需要使用filter方法,语法如下:
let results = arr.filter(function(itm,idx,array){
//和find的用法相同,不过会返回符合要求的对象数组
//找不到返回空数组})举个例子:
let arr =[
{id:1,name:'xiaoming'},
{id:2,name:'xiaohong'},
{id:3,name:'xiaojunn'},]let res = arr.filter(function(itm,idx,array){
if(itm.name == 'xiaoming' || itm.name == 'xiaohong')return true;})console.log(res)代码执行结果:

arr.map方法可以对数组的每个对象都调用一个函数,然后返回处理后的数组,这是数组最有用的、最重要的方法之一。
语法:
let arrNew = arr.map(function(itm,idx,array){
//返回新的结果})举例,返回字符串数组对应的长度数组:
let arr = ['I','am','a','student']let arrNew = arr.map((itm)=>itm.length)//return itm.lengthconsole.log(arrNew)//[1,2,1,7]
代码执行结果:

arr.sort对数组进行原地排序,并返回排序后的数组,但是,由于原数组已经发生了改变,返回值实际上没有什么意义。
所谓原地排序,就是在原数组空间内排序,而不是新建一个数组
let arr = ['a','c','b']arr.sort()console.log(arr)
代码执行结果:

注意,默认情况下
sort方法是以字母序进行排序的,也就是适用于字符串排序,如果要排列其他类型的数组,需要自定义比较方法
数字数组
let arr = [1,3,2]arr.sort(function(a,b){
if(a > b)return 1;
if(a < b)return -1;
return 0;})代码执行结果:

sort函数内部采用了快速排序算法,也可能是timsort算法,但是这些我们都不需要关心,我们只需要关注比较函数就可以了。
比较函数可以返回任何数值,正数表示>,负数表示<,0表示等于,所以我们可以简化数字比较方法:
let arr = [1,3,2]arr.sort((a,b)=> a - b)
如果想要逆序排列只需要交换一下a和b的位置既可以了:
let arr = [1,3,2]arr.sort((a,b)=> b - a)
字符串排序
别忘了字符串比较要使用str.localeCompare(str1)方法呦
let arr = ['asdfas','success','failures']arr.sort((a,b)=>a.localeCompare(b))
代码执行结果:

arr.reverse用于逆序数组
let arr = [1,2,3]arr.reverse()console.log(arr)//[3,2,1]
这个没啥好说的。
还记得字符串分割函数吗?字符串分割函数可以将字符串分割成一个字符数组:
let str = 'xiaoming,xiaohong,xiaoli'let arr = str.split(',')//['xiaoming','xiaohong','xiali']
冷门知识,
split函数有第二个参数,可以限制生成数组的长度let str = 'xiaoming,xiaohong,xiaoli'let arr = str.split(',',2)//['xiaoming','xiaohong']
arr.join()方法用途和split方法相反,可以将一个数组组合成一个字符串。
举个栗子:
let arr = [1,2,3]let str = arr.join(';')console.log(str)代码执行结果:

arr.reduce方法和arr.map方法类似,都是传入一个方法,然后依次对数组元素调用这个方法,不同的地方在于,app.map方法在处理数组元素时,每次元素调用都是独立的,而arr.reduce会把上一个元素的调用结果传到当前元素处理方法中。
语法:
let res = arr.reduce(function(prev,itm,idx,array){
//prev是上一个元素调用返回的结果
//init会在第一个元素执行时充当上一个元素调用结果},[init])试想一下,如何实现一个数字组成的数组元素和呢?map是没有办法实现的,这个时候就需要使用arr.reduce:
let arr = [1,2,3,4,5]let res = arr.reduce((sum,itm)=>sum+itm,0)console.log(res)//15
代码执行过程如下图:

arr.reduceRight和arr.reduce用途相同,只不过从右往左对元素调用方法。
数组是对象的一种特例,使用typeof无法准确的分辨二者的区别:
console.log(typeof {})//objectconsole.log(typeof [])//object二者都是对象,我们需要使用Array.isArray()方法进一步做判断:
console.log(Array.isArray({}))//falseconsole.log(Array.isArray([]))//truearr.some(func)和arr.every(func)方法用于检查数字,执行机制和map类似。
some
对每个数组元素执行传入的方法,如果方法返回true,立即返回true,如果所有的元素都不返回true,就返回false。
every
对数组的每个元素执行传入的方法,如果所有元素都返回true,则返回true,否则返回false。
举个例子:
let arr = [1,2,3,4,5]//判断数组是否存在大于2的元素console.log(arr.some((itm)=>{
if(itm > 2)return true;}))//true//判断是否所有的元素都大于2console.log(arr.every((itm)=>{
if(itm > 2)return true;}))//false在所有的数组方法中,除了sort,都有一个不常用固定参数thisArg,语法如下:
arr.find(func,thisArg)arr.filter(func,thisArg)arr.map(func,thisArg)
如果我们传入了thisArg,那么它就会在func中变为this。
这个参数在常规情况下是没什么用处的,但是如果func是一个成员方法(对象的方法),而且方法中使用了this那么thisArg就会非常有意义。
举个例子:
let obj = {
num : 3,
func(itm){
console.log(this)
return itm > this.num;//查找大于3的数字
}}let arr = [1,2,3,4,5,6,7]let newArr = arr.filter(obj.func,obj)console.log(newArr)代码执行结果:

这里我们可以看到,func中输出的this就是我们传入的thisArg值。
如果我们使用对象成员方法,同时不指定thisArg的值,就会造成this为undefined,从而导致程序错误。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要和大家分享用vue实现切换图片效果的小案例,点击按钮可以实现向前切换,向后切换和顺序切换的效果。下面我们就来看看具体的实现代码。
本篇文章给大家带来了利用JavaScript实现贪吃蛇小游戏的实例,希望对大家有帮助。
这篇文章主要为大家详细介绍了原生JS实现可拖拽登录框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
ES6中Set和Map数据结构的简单讲解 目录 Set Map 总结 Set ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成 Set 数据结构. const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4 上面代码通过add()方法向 Set 结构加入成员,结果表明 Set 结构不会添加 ...
本文实例为大家分享是如何使用javascript实现拼图游戏。对于拼图游戏,相信很多朋友都有玩过,文本给介绍的JS实现简单的拼图游戏的代码,下编觉得比较有意思,因此分享给大家作参考,下面我们就一起来看看吧。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008