js 中对数组操做比比皆是,不论是单纯前端操做数组变量,仍是后台返回的数组形式接口数据,都须要用到数组一些方法操做数组。不知道你们是否是和我同样常常忘记或混乱数组一些方法,什么 find()
,some()
,reduce()
等等,还有哪些会改变原始数组哪些返回新数组,真是一头雾水。前端
这张图是我收藏的数组方法图,上面列出了常见的数组方法及解释,界面很舒服,应该一看就懂。git
Array
专属Array
构造函数的方法常见有三种:es6
Array.isArray([]) // true Array.isArray({}) // false
下面两种方法意在建立新数组,因此我总结在一个大类里面。github
比较常见的有两种建立形式,你们能够理解分类记忆。数组
Array.from(arrayLike[, mapFn[, thisArg]])
函数
参数:ui
arrayLike
想要转换成数组的伪数组对象或可迭代对象。this
mapFn
(可选参数)
既然有规则,一定须要指定规则函数。code
thisArg
(可选参数)
可选参数,执行回调函数 mapFn 时 this 对象。对象
Array.from('foo') // ["f", "o", "o"] let m = new Map([[1, 2], [2, 4], [4, 8]]) Array.from(m) // [[1, 2], [2, 4], [4, 8]] Array.from([1, 2, 3], x => x + x) // [2, 4, 6]
Array.of(element0[, element1[, ...[, elementN]]])
参数:
任意参数
Array.of(1) // [1] Array.of(1, 2, 3) // [1, 2, 3] Array.of(undefined) // [undefined]
实例对象的方法是最多的,也是你们容易混淆的,推荐你们从三个大类去记忆。
splice()
删除元素而且向数组添加新元素array.splice(index,howmany,item1,.....,itemX)
参数:
index
:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany
:必需。要删除的项目数量。若是设置为 0,则不会删除项目。
item1, ..., itemX
: 可选。向数组添加的新项目。
var fruits = ["Banana", "Orange", "Apple", "Mango"] fruits.splice(2,1,"Lemon","Kiwi") // 结果 // [Banana,Orange,Lemon,Kiwi,Mango]
splice() 方法在 ES5 中经常使用来数组去重,至关经典。
var arr = [1,2,2,3,4,2] for(var i=0; i<arr.length; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i]==arr[j]){ //若是第一个和第二个同样,splice方法减去第二个; arr.splice(j,1) // 设置j-- 防止删除元素后,下面第一位元素遗漏 j-- } } } // arr [1, 2, 3, 4]
sort()
排序数组参数:排序规则函数或无参数
没有参数:则按照元素的字母升序,若是不是元素不是字符串的话,会调用toString()方法将元素转化为字符串的Unicode(万国码)位点,而后再比较字符。
排序规则函数:排序规则函数接受两个参数:a , b,返回一个正数或负数。这里教你们一个简单记忆方法:升序不变返回负,降序改变返回正
。
var a = [1,3,3,5,2,0] a.sort() // [0, 1, 2, 3, 3, 5] a.sort((a, b) => { return a-b // 升序不变返回负,不变指参数位置不变 }) // [0, 1, 2, 3, 3, 5] a.sort((a, b) => { return b-a // 降序改变返回正 }) // [5, 3, 3, 2, 1, 0]
下面就是两组头尾删除和添加方法,能够对应记忆
尾部操做
pop()
删除数组最后的一个元素而且返回参数: 无
push(item1, item2...)
数组的末尾添加元素并返回新长度参数:要添加的新元素
// 删除 var a = [1, 3, 5, 7, 9] a.pop() // [1, 3, 5, 7] // 添加 a.push(9, 11) // [1, 3, 5, 7, 9, 11]
头部操做
shift()
删除数组第一个元素并返回参数: 无
unshift(item1, item2...)
数组头部添加元素并返回新长度参数:要添加的新元素
// 删除 var a = [1, 3, 5, 7, 9] a.shift() // [1, 3, 5, 7] // 添加 a.unshift(0) // [0, 1, 3, 5, 7]
reverse()
颠倒数组中元素的顺序参数: 无
let a = [1,2,3] a.reverse() console.log(a) // [3,2,1]
下面是 ES6 新增的两个方法
fill(item, start, end)
用指定元素填充数组参数:
item
(必需): 要填充数组的值
start
(可选): 填充的开始位置,默认值为0
end
(可选):填充的结束位置,默认是为this.length
['a', 'b', 'c'].fill(7) // [7, 7, 7] ['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
copyWithin(target, start, end)
指定位置的成员复制到其余位置并返回替换后的新数组。参数:
target
(必需):从该位置开始替换数据。若是为负值,表示倒数。
start
(可选):从该位置开始读取数据,用哪些数据来替换,默认为 0。若是为负值,表示倒数。
end
(可选):到该位置前中止读取数据,默认等于数组长度。使用负数可从数组结尾处规定位置。
[1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5] var a=['a','b','c','d','e','f','g','h','i','j'] // 2位置开始被替换,3位置开始读取要替换的 5位置前面中止替换 a.copyWithin(2,3,5) // ["a","b","d","e","e","f","g","h","i","j"]
这里能够总结下:
替换先后数组的长度保持不变;
读取数据在终止位置的前一个位置中止,而且保存这个位置的数据不动
读取出来了多少数据,就须要在前面按顺序替换掉多少数据。
上面大类属于能够改变原数组的实例方法,下面一大类固然就是不改变原数组了。
slice(start, end)
截取数组片断,返回新数组参数:
start:(可选)规定从何处开始选取,负数表示从数组尾部算起
end: (可选)没指定则一直截取到数组最后一个元素,包括最后一个。指定了则截取到指定位置前一个元素。
[1, 2, 3, 4].slice() // [1, 2, 3, 4] [1, 2, 3, 4].slice(1) // [2, 3, 4] [1, 2, 3, 4].slice(1, 3) // [2, 3]
join(str)
按照链接符将数组链接成字符串并返回字符串参数:
没有参数: 则使用 ,
链接
有参数: 按照参数指定链接符链接
let a= ['hello','world'] let str=a.join() // 'hello,world' let str2=a.join('+') // 'hello+world'
特别注意:当原始数组中含有对象时,使用 join()
方法链接时会把对象转成 [object Object]
字符串,看下面:
var b = [{name: 'pubdreamcc', age: 24}, 'test'] b.join() // [object Object],test
cancat(item1,item2...)
合并多个数组并返回参数:
能够是数组对象:等待合并的数组
也能够是具体的值(元素): 等待合并的元素
var a = [1, 2, 3] var b = [4, 5, 6] a.concat(b) // [1, 2, 3, 4, 5, 6] a.concat(4, 5, 6) // [1, 2, 3, 4, 5, 6]
toLocaleString()
数组转字符串参数: 无
该方法一样也是数组转字符串,是将数组中每个元素调用自身的toLocaleString()
方法后用 ,
链接获得的字符串。
能够理解为先把数组中每一个元素都调用下 toLocaleString()
方法,再把获得的结果数组调用 join()
方法。
let a=[{name:'pubdreamcc'},24,'cc',new Date()] a.toLocaleString() // [object Object],24,cc,2019/7/18 下午1:52:20
toString()
数组转字符串这个方法应该比较熟悉,它是定义在 Object
原型上面的一个方法,用来把一个对象转成字符串,在这里其实同 join(无参数)
方法效果同样。
实际开发中不推荐使用。
indexOf(item, start)
查找数组某个元素并返回其第一次出现位置下标参数:
item
(必需): 须要查找的元素值
start(可选)
: 规定在数组中开始检索的位置(0-array.length)
若是没找到,返回 -1
var a = [1, 2, 1] a.indexOf() // -1 a.indexOf(1) // 0 a.indexof('1') // -1
注意: indexOf()不能识别NaN, 由于 NaN 与任何数不相等,包括自身。
lastIndexOf(item, fromIndex)
查找数组某个元素并返回其最后一次出现位置下标该方法与 indexOf()
刚好相反,查找不到一样返回 -1
参数:
item
(必需): 被查找的元素
fromIndex
(可选): 逆向查找开始位置,默认值数组的长度-1,即查找整个数组。
let a=['cc',4,'pubdreamcc',1,2,'pubdreamcc',3,4,5,'pubdreamcc'] // 数组长度为10 // let b=a.lastIndexOf('pubdreamcc',4) // 从下标4开始往前找 返回下标2 // let b=a.lastIndexOf('pubdreamcc',100) // 大于或数组的长度 查找整个数组 返回9 // let b=a.lastIndexOf('pubdreamcc',-11) // -1 数组不会被查找 let b=a.lastIndexOf('pubdreamcc',-9) // 从第二个元素4往前查找,没有找到 返回-1
下面这个方法是 ES7 中新增
includes(item, fromIndex)
查找数组是否包含某个元素返回布尔参数:
item
(必需):要查找的元素
fromIndex
(可选): 默认值为0,参数表示搜索的起始位置,接受负值。正值超过数组长度,数组不会被搜索,返回false。负值绝对值超过长数组度,重置从0开始搜索。
注意: includes()方法能够检测 NaN
let a=['cc','pubdreamcc',1,NaN] // let b=a.includes(NaN) // true 识别NaN // let b=a.includes('pubdreamcc',100) // false 超过数组长度 不搜索 // let b=a.includes('pubdreamcc',-3) // true 从倒数第三个元素开始搜索 // let b=a.includes('pubdreamcc',-100) // true 负值绝对值超过数组长度,搜索整个数组
总结完了数组的基本两大类方法后,接下来咱们开始上数组的遍历方法。
数组的遍历也是很是重要,在实际项目开发中用的不少,不一样的场景使用不一样的遍历方法能够加快咱们开发速度。
数组的遍历并不会改变原始数组。
forEach(func, thisValue)
遍历数组,为每一项执行一次回调函数参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
array.forEach((value, index, arr) => {}, thisValue)
关于 forEach()
这里须要注意的几点:
没法中途退出循环,只能用return退出本次回调,进行下一次回调。
它老是返回 undefined值,即便你return了一个值。
若是在回调中须要更改数组中的基本类型数据,请使用 array[index] = XXX
,不能直接给 value
赋值。
every(func, thisValue)
检测数组全部元素是否都符合判断条件返回布尔参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
若是有一项元素执行回调返回false
,剩余元素再也不执行回调,整个方法返回 false
若是全部元素都知足条件,则整个方法返回 true
。
[12, 5, 8, 130, 44].every(x => x >= 10) // 判断数组中每一个元素是否大于或等于 10 // false
some(func, thisValue)
检测数组中的是否有知足条件的元素返回布尔参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
some()
刚好和 every()
相反,只要数组中有一项知足条件判断,则整个方法返回 true
,若是所有元素都不知足条件,则返回 false
。
[12, 5, 8, 130, 44].every(x => x >= 10) // 判断数组中是否有元素大于或等于 10 // true
filter(func, thisValue)
按照条件过滤原始数组返回新数组参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
var arr1 = [1, 3, 8, 4, 6, 7, 2] var arr2 = arr1.filter((item, index)=>{return item > 5}) // 从原数组中过滤出大于 5 的元素 // [6, 7, 8]
map(func, thisValue)
对数组中每一个元素进行一次回调,返回回调返回的元素组成的数组参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
能够发现这个几个方法的参数都同样,只是返回值不一样而已。
let a1 = ['1','2','3','4'] let a2 = a1.map((value, index) => { return +value }) // [1, 2, 3, 4]
reduce(func, initialValue)
为数组提供一个累加器,把数组合并为一个值reduce()
方法不少人搞的不是很清楚,也包括本身,讲真的这个方法还真有点绕,可是弄明白以后确实能够给咱们带来不少的便利。
参数:
func
(必需):指定的回调函数
initialValue
(可选):传递给回调的初始值,说白了便是回调第一个参数 prev
的初始值。
func(prev, curr, currIndex, arr)
参数解析:
prev
(必需): 函数上一次 return
回来的值。若是提供了 initialValue
,则初始值为initialValue
,若是没有提供,则 prev
初始值为数组第一个元素。
curr
(必需): 当前执行回调时,数组中的元素
currIndex
(可选): 当前执行回调时,数组中元素的下标
arr
(可选):当前元素所属的数组对象
利用 reduce() 方法 咱们操做数组更加方便,例如一些常见的例子:
var arr = [1, 3, 5, 7, 9] var sum = arr.reduce((prev, curr) => { return prev+curr }) // 25
var arr = ['cc', 'cc1', 'cc', 'cc2', 'cc1', 'cc', 'cc5'] var obj = arr.reduce((prev, curr) => { if (!prev[curr]) { prev[curr] = 1 } else { prev[curr] += 1 } return prev }, {}) // {'cc': 3, 'cc1': 2, 'cc2': 1, 'cc5': 1}
reduceRight(func, initialValue)
从右至左的方向把数组累加为一个值该方法同上面讲的 reduce() 方法使用基本一致,只不过累加的方式为数组的末尾向前将数组中的数组项作累加。
下面几个关于遍历的方法是 ES6 新增的,一种关于查找,一种是关于遍历。
find(func, thisValue)
找出第一个符合条件的数组成员并返回参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
若是没有找到,则返回 undefined
var arr = [1, 3, 5, 7] var num = arr.find((item, index) => {return item > 1}) // 3
findIndex(func, thisValue)
找出第一个符合条件的数组成员下标并返回参数:
func
(必需):指定的回调函数
thisValue
(可选):当执行回调函数时this
绑定对象的值,默认值为undefined
若是没有找到则返回 -1
var arr = [1, 3, 5, 7] var index = arr.findIndex((item, index) => {return item > 1}) // 1
注意:
这两个方法均可以识别 NaN
,弥补了indexOf
的不足。
keys()&values()&entries()
遍历键名、遍历键值、遍历键名+键值这三种方法都会返回一个新的 Array Iterator
对象
array.keys()
返回一个包含数组全部下标组成的 Iterator。
array.values()
返回一个包含数组全部元素组成的 Iterator。
array.entries()
返回一个包含数组元素加下标组成的 Iterator。
返回的 遍历器 能够用 ES6 提供的 for...of
循环来遍历。
for (let index of ['pubdreamcc', 'pubdreamcc1'].keys()) { console.log(index) } // 0 // 1 for (let item of ['pubdreamcc', 'pubdreamcc1'].values()) { console.log(item) } // 'pubdreamcc' // 'pubdreamcc1' for (let [index, item] of ['pubdreamcc', 'pubdreamcc1'].entries()) { console.log(index, item) } // 0 "pubdreamcc" // 1 "pubdreamcc1"
花了将近一下午的时间来整理出数组的一些方法,但愿本身可以更加清晰包括理解 它们 的用法,固然最最重要仍是在平时撸码的过程当中可以运用到对的地方加快开发效率,毕竟我们学技术仍是要服务于产品,把技术变现呢。
最后,但愿你可以细心看完,保证你会有不同的收获。