js中数组API详解
数组在平时的开发过程使用频率非常高,熟练掌握数组的各种api用法很有必要,在此对数据的所有api做一次详细介绍
数组提供的api主要分为 构造函数自身方法,改变自身、不改变自身、遍历数组四类
ES2019新增方法
- flat
- 作用:数组降维,返回一个新数组,不改变原来数组
- 接受参数:Number类型,默认为1,根据参数来降低维度层次
const arr = [2,3,[4],[5,[6,[7]]]] arr.flat(1) //=>[2,3,4,5,[6,[7]]] arr.flat(2) // => [2,3,4,5,6,[7]] arr.flat(Infinity) //=>[2,3,4,5,6,7] console.log(arr) // [2,3,[4],[5,[6,[7]]]]
- flatMap
- 作用:对数据进行统一变化处理,返回一个新数组,不改变原数组
- 接受参数:func
const arr = [1,2,3] //对每一个元素做处理 arr.flatMap(x => x*2) // [2,4,6] //对一个元素多处理,返回多个对应的值,但是返回必须是数组,里面的类型不限制 arr.flatMap(x => [x,x*2] // [1,2,2,4,3,6] arr.flatMap(x=>[{test:x}] // [{test:1},{test:2},{test;3}] //如果返回{}会全部返回undefined arr.flatMap(x => {x:x}) // [undefined,undefined,undefined]
Array构造函数的方法
- of
Array.of():将参数依次转化为数组中的一项,然后返回这个新数组,功能和Array()基本一致(传单个数字除外)
Array.of(12,'dere',18) // => [12,'derek',18] Array.of(8.0) // => [8] Array(8.0) // => [undefined * 8]
- from
Array.from():将一个类数组对象转化为一个数组,返回新数组,不改变原对象
- 语法:Array.from(obj,fn,thisArg)
- obj: 需要转为数组的对象
- fn: 对对象进行加工的方法
- thisArg: this作用域
- 注意: 对象的key只能是数字,且不能超过length的长度,先返回满足条件的key值
// 对象的key是数字,正常转化 let obj = {0: 'derek', 1: 18, 2: 'M', length: 3 } let arr = Array.from(obj,(val,index)=>{ val index return val },obj) arr // => ['derek',18,'M'] // 对象的key值不是数字的返回undefined let obj = {name: 'derek', 1: 18, 0: 'M', length: 3 } let arr = Array.from(obj,(val,index)=>{ val index return val },obj) arr // => ['M',18,undefined]
- isArray
Array.isArray(): 判断一个变量是否是一个数组 语法:Array.isArray(arr)
let arr = [1,2,3] let a = Array.isArray(arr) a// => true
改变自身的api
-
push
push(): 在目标数组的尾部压入一个元素,并且返回这个元素最新的length
let arr = ['a','b','c'] let len = arr.push('d') console.log(arr,len) // => ['a','b','c','d'] 4
-
unshift
unshift(): 在目标数组的顶部压入一个元素,并且返回这个元素的length
let arr = ['a','b','c'] let len = arr.unshift('d') console.log(arr,len) // => ['d','a','b','c'] 4
-
pop
pop(): 在目标数组的尾部压出一个元素,并且返回这个被压出元素
let arr = ['a','b','c','d'] let a = arr.pop() console.log(arr,a) // => ['a','b','c'] 'd'
-
shift
shift(): 在目标数组的顶部压出一个元素,并且返回这个被压出元素
let arr = ['a','b','c','d'] let a = arr.shift() console.log(arr,a) // => ['b','c','d'] 'a'
-
reverse
reverse(): 将数组顺序进行颠倒,第一个成为最后一个,最后一个成为第一个,返回当前数组
let arr = ['a','b','c','d'] let arr2 = arr.reverse() console.log(arr) // => ['d','c','b','a'] console.log(arr2) // => ['d','c','b','a'] console.log(arr2===arr) // => true
-
sort
sort(): 将数组顺序进行快速排序,返回当前数组
- a:默认排序:不传参数(arr.sort()),数组元素将按照各自转换为字符串的Unicode(万国码)位点顺序排序
- b:自定义排序:传入自己想要的排序方法(arr.sort((a,b) => a-b)),会按照顺“从小到大”的顺序排序
// 对数字数组进行排序 let aaa = [3,4,52,64,234,6,8] let arr = aaa.sort() let arr1 = aaa.sort((a,b)=> a-b) console.log(arr) // => [234,3,4,52,6,64,8] console.log(arr1) // => [3,4,6,8,52,64,234] ------------------------------------- // 对元素是对象的数组进行快速排序 let arr = [{name: 'derek',age: 18 },{ name: 'tom', age: 28 },{ name: 'lily', age: 18 },{ name: 'lucy', age: 22 }] let aa = arr.sort((a,b)=> a.age-b.age) console.log(aa) // => [{name:'derek',age:18},{ name: 'lily', age: 18 },{ name: 'lucy', age: 22 },{ name: 'tom', age: 28 }]
注意:
使用sort()进行数组排序时,数组元素少于10个时,用的是插入排序法,排序稳定数组元素大于10个时,用的是快速排序,排序不稳定,排序可能会出错解决方案: array.sort((a,b)=> a - b || array.indexof(a)-array.indexof(b))
ES2019对sort方法进行了优化,内部排序方法已经由quickSort改为了TimSort,解决了排序不稳定的问题
-
splice
splice(): 可以对数组进行插入,删除,替换的操作,返回一个包含删除的元素的数组 语法:arr.splice(start,count,item1,item2) start: 开始删除的位置,从0开始,如果大于数组的长度则为arr.length count: 删除元素的数量,为0时,如果存在第三个元素,就是数组插入元素 item1、item2:往数组中添加的元素
//删除元素 let arr = ['tom','derek','lily','lucy'] let a = arr.splice(0,2) console.log(arr) // => ['lily','lucy'] console.log(a) // => ['tom','derek'] //替换元素 let arr = ['tom','derek','lily','lucy'] let b = arr.splice(1,2,'david') console.log(arr) //=> ['david','lily','lucy'] console.log(b) // => ['tom','derek'] //插入元素 let arr = ['tom','derek','lily','lucy'] let c = arr.splice(2,0,'nina') console.log(arr) // => ['tom','derek','nina','lily','lucy'] console.log(c) // => []
注意:当删除开始数据大于数组长度时,默认为数组尾部压入元素
let arr = ['tom','derek','lily','lucy'] let b = arr.splice(5,2,'david') console.log(arr) //=> ['tom','derek','lily','lucy','david'] console.log(b) // => []
-
copyWithin
copyWithin(): 数组内的元素替换,就是替换元素和被替换元素都时数组内的元素,返回改变后的数组
- 语法: array.copywithin(target,start,end)
- target: 被替换元素的开始下标
- start:替换元素的开始下标,可以为负数
- end:替换元素的结束下标,不填默认为array.length,可以为负数
let arr = [1,2,3,4,5] let result = arr.copyWithin(0,2,3) console.log(result === arr,arr) // => true [3,2,3,4,5] let arr = [1,2,3,4,5] arr.copyWithin(1,3) console.log(arr) // =>[1,4,5,4,5] let arr = [1,2,3,4,5] arr.copyWithin(1,-2,-1) console.log(arr) // =>[1,4,3,4,5]
-
fill
fill(): 用于对数组中的指定位置区间的元素替换为指定的值,返回改变后的原数组
- 语法:array.fill(val,start,end)
- val: 指定替换的值
- start: 被替换的开始下标,可以为负数
- end: 被替换的结束下标,可以为负数,不填为数组长度
let arr = [1,2,3,4,5] const a = arr.fill(6,1,3) console.log(a===arr,arr) // => true [1,6,6,4,5] let arr = [1,2,3,4,5] const a = arr.fill(6,-3,-1) console.log(arr) // => [1,2,6,6,5]
不改变自身的api
-
concat
concat(): 将传入的数组或者元素合并,组成一个新数组返回
- 语法:arr.concat(val1,val2...)
- 注意:参数可以是数组时,只能降一个纬度合并
let arr = [1,2,3] let aaa = arr.concat(1,2,[3,4,5],[6]) console.log(aaa,arr) // => [1,2,3,4,5,6,7] [1,2,3] let bbb =arr.concat(1,[2,3,[4,5,6]]) console.log(bbb) // => [1,2,3,[4,5,6]]
-
join
join(): 将数组中的元素以自定义的一个链接符拼接为一个字符串,并返回
- 语法:array.join(val)
- val: 元素之间的链接符,默认为','
let arr = [1,2,3,4] arr.join() // => 1,2,3,4 arr.join('-') // => 1-2-3-4
-
slice
slice(): 将数组中的部分数据复制到一个新数组中,并返回这个数组
- 语法: array.slice(start,end)
- start: 复制数组的开始下标,可以为负数(-2 => array.length-2
- end: 复制数组的结束下标,不包含该元素,不传默认为到最后一个元素
- 注意:不传任何参数是,可以做浅拷贝slice()
let arr = [1,2,3,4,5,6] arr.slice(1,4) // => [2,3,4] arr.slice(2) // => [3,4,5,6] arr.slice(-3,5) // => [4,5,6]
-
toString
toString(): 返回数组的字符串形式,等效于join()
- 语法:array.toString()
- 注意:数组和字符串元素进行+拼接时,会自动调用toString方法
let array = ['a','b','c','d'] array.toString() // => a,b,c,d array+'e' // => a,b,c,de
-
toLocalString
toLocalString(): 类似toString()的变型,该字符串由数组中的每个元素的 toLocaleString() 返回值经调用 join() 方法连接(由逗号隔开)组成
- 语法:array.toLocalString()
- 注意:数组中的各个元素将调用各自的toLocalString方法
- Object:Object.prototype.toLocaleString()
- Number:Number.prototype.toLocaleString()
- Date:Date.prototype.toLocaleString()
let arr = [{name: 'derek'},22,'M',new Date()] arr.toLocalString() // => '[object,object],22,M,2019/3/5 1:06:23PM'
-
indexOf
indexOf(): 用于查找数组中元素出现的第一次索引位置,并返回,没有则返回-1
- 语法: array.indexOf(el,start)
- el: 查找的目标元素
- start: 开始查找的下标位置
- 注意:
- start不传,默认为0
- start > array.length,则返回-1
- start < 0 ,从array.length + start 的位置开始
- start + array.length < 0,会查到整个数组
let arr = [1,3,4,5,7,9,0,7,45,6,8] let a =arr.indexOf(1) // => 0 let b = arr.indexOf(1,3) // => -1 let c = arr.indexOf(7,-5) // => 7 let d = arr.indexOf(7, -10) // => 4
-
lastIndexOf
lastIndexOf(): 元素在数组中最后出现的下标,没有则返回-1
- 语法: array.lastIndexOf(el,start)
- el: 查找的目标元素
- start: 开始查找的下标位置
- 实例: 参考indexOf
-
includes
includes(): 判断数组中是否存在某个元素,存在返回true,不存在则返回false
- 语法: array.includes(el,start)
- el: 要查找的目标元素
- start: 开始查找的下标,默认为0
var array = [1, 2, NaN]; array.includes(1) // true array.includes(NaN) // true array.includes(2,-4) // true
用于数组遍历的api
- forEach
forEach(): 指定数组中的每个元素都执行一次传入的函数,返回undefinded
- 语法: arr.forEach(fn,thisArg)
- fn: 每个元素需要执行的方法,接受三个参数 fn(el,index,array)
- el: 当前处理的元素
- index: 正在处理元素的下标
- array: 数组本身,一般不写
- thisArg: fn函数内的this对象
- 注意: 将为数组中每一项执行一次 fn 函数,那些已删除,新增或者从未赋值的项将被跳过(但不包括值为 undefined 的项)
let arr = [1,2,3,4,5] let a = arr.forEach((el,index)=> { arr[index] = el * index }) console.log(a) // => undefined console.log(arr) // => [0,2,6,12,20]
- map
map(): 使用传入的函数处理数组中的每个函数,并且将每个返回值组成新数组并返回
- 语法: arr.map(fn,thisArg)
- fn: 每个数组元素执行的方法
- el: 当前处理的元素
- index: 正在处理元素的下标
- array: 数组本身,一般不写
- thisArg: fn函数内的thisArg,一般不传
let arr = [1,2,3,4] let result = arr.map((item,index) => item * index ) console.log(result) // => [0,2,6,12] console.log(arr) // => [1,2,3,4]
- filter
filter(): 对数组中的每个元素调用传入的函数,将满足条件的元素组成一个新数组并返回
- 语法: arr.filter(fn)
- fn: 判断元素是否满足目标元素的条件函数
let arr = [1,2,3,4,5,6,7] arr.filter(item=>item> 3) //=> [4,5,6,7] arr.filter(item=>item>8) // => [] arr.filter(item => item % 2 === 0) // => [2,4,6,8]
- reduce
reduce(): 方法接收一个方法作为累加器,数组中的每个值(从左至右) 开始合并,最终为一个值
- 语法: arr.reduce(fn,initVal)
- fn: 表示在数组中每个元素执行的函数,接收4个参数
- previousValue 上一次调用回调返回的值,或者是提供的初始值
- value 数组中当前被处理元素的值
- index 当前元素在数组中的索引
- array 数组自身
- initVal: 累加初始值
- 注意: 当 fn 第一次执行时
- 如果 initialValue 存在,那么第一个 previousValue = initialValue, item = 数组中的第一个值;
- 如果 initialValue 不存在,那么 previousVaule = 数组中的第一个值,item =数组中的第二个值。此时如果数组为空,那么将抛出 TypeError。
- 如果数组仅有一个元素, 但数组为空,那么fn不会被执行,数组的唯一值将被返回
//用于求和 let arr = [1,2,3,4,5] arr.reduce((prev,value)=>value * prev,0) // => 120 //用于其他应用 let arr = [1,2,3,4,5] let result = arr.reduce = ((prev,value,index) => { value > 2 ? prev.push(value) return prev },[]) console.log(result) // => [3,4,5]
- reduceRight
reduceRight():方法接收一个方法作为累加器,数组中的每个值(从右至左) 开始合并,最终为一个值
- 语法: arr.reduce(fn,initVal)
- fn: 表示在数组中每个元素执行的函数,接收4个参数
- 具体用法参考上述的reduce函数
- some
some(): 对比数组中的所有元素,只要有满足条件的就返回true,并结束循环,全部不满足就返回false
- 语法: arr.some(fn)
- fn: 每个元素执行的方法
let arr = [1,2,3,4,5,6] arr.some(item => item = 3) // => true arr.some(item => item > 8) // => false
- every
every(): 对比数组中的所有元素,全部满足条件则返回true,只要有一个不满足就返回false
- 语法:arr.every(fn)
- fn: 每个元素执行的方法
let arr =[1,2,3,4,5] arr.every(item => item > 0) // => true arr.every(item => item > 2) // => false
- find
find(): 返回数组中第一个满足条件的元素(如果有的话), 如果没有,则返回undefined
- 语法: array.find(fn,thisArg)
- fn: 查找条件函数
- thisArg: fn函数内部运行的this对象,一般不传
let arr = [1,2,3,4,5,6] arr.find(item => item>3) // => 4 arr.find(item => item < 1) // => undefined
- findIndex
findIndex(): 返回数组中第一个满足条件的元素的索引(如果有的话), 如果没有,则返回-1
- 语法: array.findIndex(fn,thisArg)
- fn: 条件函数
- thisArg: fn函数内部运行的this对象,一般不传
let arr = [1,2,3,4,5] arr.findIndex(item => item > 3) // => 3 arr.findIndex(item => item < 0) // => -1
- keys
keys(): 返回数组索引的迭代器
- 语法: array.keys()
let arr = ['a','b','c'] let aa = arr.keys() console.log(aa.next()) // => Object {value: 0, done: false} console.log(aa.next()) // => Object {value: 1, done: false} console.log(aa.next()) // => Object {value: 2, done: false} console.log(aa.next()) // => Object {value: undefined, done: true} // 注意:用于对象的keys let obj = {name: 'derek',age:18} Object.keys(obj) // => ['name','age']
- values
values(): 返回数组值的迭代器
- 语法: array.values()
let arr = ['a','b','c'] let aa = arr.values() console.log(aa.next()) // => Object {value: 'a', done: false} console.log(aa.next()) // => Object {value: 'b', done: false} console.log(aa.next()) // => Object {value: 'c', done: false} console.log(aa.next()) // => Object {value: undefined, done: true} // 注意:用于对象的values let obj = {name: 'derek',age:18} Object.values(obj) // => ['derek',18]
- entries
entries(): 返回一个数组迭代器对象,该对象包含数组中每个索引的键值对
- 语法: array.entries()
let arr = ['derek','tom'] let aa = arr.entries() console.log(aa.next()) // => {value:[0:'derek],done: false} console.log(aa.next()) // => {value:[1:'tom],done: false} console.log(aa.next()) // => {value:undefined,done: true} // 对象中用entries let obj = {name: 'derek',age:18} console.log(Object.entries(obj)) // => [[name:'derek'],[age:18]]