JavaScript数组及常用方法汇总
数组类型在JavaScript中经常用到。数组中可以包含任何类型的数据,包括对象。
数组的检测
检测一个数组不能用typeof
方法,因为数组不是基本类型数据,typeof
只适合用于检测基本数据类型。
在实际工作中常用的数组检测方法:
-
instanceof
instanceof
可以检测一个对象是否是Array类型
的数据:let arr = [1,2,3,4]; arr instanceof Array; // true
instanceof
存在一个臭名昭著的问题,那就是在不同的iframes
中instanceof
方法并不是同一个,因为它是全局对象的方法,如果页面有多个框架,window对象就会有多个。 -
Array.isArray()
可以直接调用
Array.isArray(value)
来检测某个值是否是数组。Array.isArray(arr); // true, 这里IE8及以下不兼容
Array.isArray()
在一定程度上要优于instanceof
,解决Array.isArray()
兼容性的解决方案如下:if (!Array.isArray) { Array.isArray = function(params) { return Object.prototype.toString.call(params) === '[object Array]'; }; }
-
Object.prototype.toString.call()
从
Array.isArray()
中可以看到,调用Object.prototype.toString.call(params)
时,它会返回一个字符串,表示当前数据的数据类型:它是对象中的Array类型。这个方法的强大之处在于它可以已检测任何复杂类型的数据:
function func(){}; Object.prototype.toString.call(func); // '[object Function]' let regs = /cc/g; Object.prototype.toString.call(regs); // '[object RegExp]' let date = new Date(); Object.prototype.toString.call(date); // "[object Date]" let obj = {}; Object.prototype.toString.call(obj); // "[object Object]"
-
Json.Stringfy()
Json.Stringfy()
主要用于将某个值转换成字符串,如果作用于数组,那么它将会返回如"[...]"
格式的字符串,此方法常用于检测某个值是否是空数组(在不知道值是否是数组的情况下):let arr = []; Json.Stringfy(arr); // "[]"
不改变原始数据的数组方法:
-
toString()
、valueOf()
、toLocaleString()
三种方法都是继承自Object的属性,调用
toString()
方法和toLocalString()
会返回每个值以字符串拼接成的逗号分隔的字符串,valueOf()则会返回原数组:let arr1 = [1,2,3]; arr1,toString(); // '1,2,3' arr1,toLocalString(); // '1,2,3' arr1,valueOf(); // [1,2,3],可以用于复制数组
alert()
方法传入数组时会隐式调用数组的toString()
方法。 -
join()
转换join()
会将数组 按照某个特定的字符拼接,返回一个新的数组,如果不传参或者undefined,默认以逗号分隔:let arr2 = [2019,8,17]; arr2.join('-'); // "2019-8-17" arr2.join('.'); // "2019.8.7" arr2.join(); // "2019,8,17" arr2.join(null); // "2019null8null17"
-
concat()
拼接concat()
用于数组的拼接,它将会返回一个新数组,不改变原始数组,传入的任何参数都会被拼接到新数组中let arr = [1,2,3,4]; arr.concat(5,6,7); // [1,2,3,4,5,6,7] arr.concat([3,4,5]); // [1,2,3,4,3,4,5] arr.concat(undefined); // [1,2,3,4,undefined] arr.concat(); // [1,2,3,4],可以用于复制数组
-
slice()
获取slice()
用于获取数组某个索引范围的数组,它返回的是一个新数组,不会改变原始数据。可以传入两个参数,slice()
方法的规则如下:当没有参数时,默认获取所有数据,相当于复制;
当只有一个参数时,默认获取从该参数到数组末尾的数据;
当参数有负数时,不管是第几个参数为负值,默认将其加上数组的length再获取数据;
第一个参数被获取,第二个参数不被获取(左闭右开);
如果参数为
null
,undefined
,NaN
中的任何一个,将其转换成0再获取,如果为其他数据类型,调用Number()
方法将其转换成数字再获取,如果不能转换成数字,则报错。let arr = [1,2,3,4,5,6,7,8]; arr.slice(); // [1,2,3,4,5,6,7,8] arr.slice(6); // [7,8] arr.slice(2,5); // [3,4,5] arr.slice('2',[5]); // [3,4,5] arr.slice(null,{toString: () => 5}); // [1,2,3,4,5]
改变原始数据的数组方法:
-
splice()
删除、插入、替换splice()
用于删除、插入、替换数组中的某些值,它将会改变原始数据,而且始终都会返回一个数组。规则如下:如果没有参数,返回空数组,原数组不变;
如果只有一个参数,参数表示起始索引,返回从起始索引删除到数组的最后一项,原数组被改变;
如果只有两个参数,表示将要删除数组的值,第一个参数表示起始索引,第二个参数表示删除的项数;
如果至少有三个参数,想要插入一些值,第一个参数表示起始索引,第二个参数为0,后面的参数表示要插入的值,可以是任意项(只要不越界),返回空数组;
如果至少有三个参数,想要替换一些值,第一个参数表示起始所引,第二个参数表示要替换的项数,后面的参数表示要替换的值,可以是任意项,返回被替换的数组;
如果第一个参数为负数,则将参数加上数组的length再进行删除、插入、替换操作,如果第二个参数为负数,返回空数组。
如果前两个参数为
null
,undefined
,NaN
中的任何一个,将其转换成0再操作,如果为其他数据类型,调用Number()
方法将其转换成数字再进行相关操作,如果不能转换成数字,则报错。let arr = [1,2,3,4,5,6,7,8,9]; arr.splice(); // [] arr.splice(8); // [9], arr = [1,2,3,4,5,6,7,8] arr.splice(-2); // [7,8], arr = [1,2,3,4,5,6] arr.splice(NaN); // [1,2,3,4,5,6], arr = []; arr = [1,2,3,4,5,6,7,8,9]; // 重新初始化arr arr.splice(4,3); // [5,6,7], arr = [1,2,3,4,8,9]; arr.splice(-1,3); // [4,8,9], arr = [1,2,3] arr.splice(1,2,2,3,4,5,6,7,8,9); // [2,3], arr = [1,2,3,4,5,6,7,8,9] arr.splice('5', '6'); // [6,7,8,9] arr = [1,2,3,4,5] arr.splice([1], {toString: ()=> 2}, '6'); // [2,3] arr = [1,'6',4,5]
-
push()
、pop()
、shift()
、unshift()
数组的栈方法,
push()
表示向数组末尾插入一条数据,pop()
表示从数组末尾删除一条数据,shift()
表示从数组首位删除一条数据,unshift()
表示向数组首位插入一条数据。插入的栈方法返回的是数组的length,删除的栈方法返回的是被删除的数据,如果删除的栈方法没有传入参数,则返回的是数组的length。let arr = [1,2,3,6] arr.push(4); // 5, arr = [1,2,3,6,4] arr.shift(); // 4, arr = [2,3,6,4] arr.pop(); // [4], arr = [2,3,6] arr.unshift(8); // 4, arr = [8,2,3,6] arr.push(); // 5, arr = [8,2,3,6]
-
reverse()
反序reverse()
用于将数组进行反序转换,它会改变原始数据类型,返回的是反序后的数组。let arr = [1,2,3]; arr.reverse(); // [3,2,1], arr = [3,2,1]
-
sort()
排序sort()
默认按照升序排列数组,它会改变原始数据类型,返回的是排序后的数组。默认的排序方法比较的是字符串形式的数据,它会将数据一位一位地进行比较:
let arr = [1,20,15,12,22,9]; arr.sort(); // [1, 12, 15, 20, 22, 9] // 比较的是字符串的数据
如果想让其按照我们的想法来进行比较,需要在
sort()
中定义一个方法,这个方法默认有两个参数,其中第一个参数表示数组后一项的值,第二个参数表示数组前一项的值,sort()
通过方法返回的数值的正负来进行排序arr.sort((val1, val2) => val1-val2); // val1表示后一项,如果val1>val2,返回正数,升序排列 arr.sort((val1, val2) => val2-val1); // val2表示前一项,如果val2>val1,返回正数,降序排列
数组迭代方法
数组迭代方法在实际项目中经常用到,对数据进行相关操作的时候需要合理选取这些方法,能提高前端开发的效率,在性能上也有良好的提升。IE8及以下不适合使用这些方法。
-
every()
和some()
判断every()
和some()
都表示对数组中的数据进行判断,判断的方法要我们自己定义,但是有三个固定参数item(当前项的值),index(当前项的索引),array(原始数组),结果都返回一个布尔值。但是规则不同,every()
表示数组中每一项都满足的情况下才返回true,而some()
表示数组只要有一项满足就返回true.let arr = [1,47,8,4,20]; arr.every((item, index, array) => item > 10); // false arr.some((item, index, array) => item > 10); // true
-
filter()
过滤filter()
表示对数组中的数据进行过滤,方法也需要我们自己定义,参数为item,index和array,返回的是过滤后的数组,它不会改变原始数据。let arr = [3,5,7,6,8]; arr.filter((item) => item % 2 === 0); // [6,8]
-
map()
和forEach()
map()
和forEach()
都是对数组进行循环,执行我们想要的操作,它们之间的区别就是map()有返回值,返回的是一个数组,length和原数组相等,forEeach()
则没有返回值。let arr = [1,2,3,4,5]; arr.map((item) => item > 3); // [false, false, false, true, true] arr.forEach(item => { console.log(item); // 1,2,3,4,5 })
-
reduce()
和reduceRight()
reduce()
和reduceRight()
都是归并数组的方法,类似于递归函数,它们会自动自调用。归并的操作需要我们自己定义,传入的方法有四个参数prev(前一个参数),next(下一个数组的值),index(next值的索引)和array(原始数组),两个方法都有一个返回值,这个返回值会被传入到prev中,从而进行下一步函数的调用。let arr = [1,2,3,4,5]; let result = arr.reduce((prev, next, index) => { console.log(prev, next, index); return prev + next; }); //1,2,1 第一步,传入第一个参数和第二个参数, 返回相加的结果 //3,3,2 第二步,将第一步的返回值赋值给prev,next表示第三个参数,返回相加的结果 //6,4,3 第三步,.... //10,5,4 直到最后一条数据 // result = 15
reduceRight()
则表示从数组的最后一项开始遍历数组,这里不再赘述。
其他方法
-
indexOf()
和lastIndexOf()
查找数据的索引值,如果数组中没有对应的数据或者不传入参数,则返回-1,都可以传入两个参数,第一个表示查找的值,第二个表示开始查找的索引位置,
lastIndexOf()
表示从后向前开始查找。查找的参数第二个可以为负值,也可以为其他类型的数据,转换规则同slice()
方法。 -
includes()
ES7新增的数组方法,判断数据是否在数值中,返回true或者false,传入的参数同上。
-
flat()
和flatMap()
ESNext,将二维数组转换成一维数组。
flatMap()
在转换的基础上新增了遍历,可以同时对每一项数据作一些逻辑处理。
数组方法基本就这么些个了,如有错误的地方,欢迎指正。
自强不息怀壮志以长行,厚德载物携梦想而抚凌。。