数组常用方法

最详细、最权威的方法见js高级程序设计 6.2 Array(推荐阅读)

数组的遍历方法

for 循环

  • 可以响应 break continue, return报错
  • 改变原数组
    使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显
1
2
3
for(var j = 0,len=arr.length; j < len; j++) {

}

for-in 循环(不建议用来遍历数组)

  • 可以响应 break continue, return报错
  • 改变原数组
  • 能遍历到实例的属性或者是原型上的属性(所以不推荐数组使用)
    for-in循环是为了遍历对象而设计的,事实上for-in也能用来遍历数组,但定义的索引i是字符
1
2
3
4
5
6
7
8
9
10
//for-in遍历数组
for(var i in arrTmp){
console.log(i+": "+arrTmp[i])
}
//for-in会遍历到数组的可枚举属性
arrTmp.name="myTest";
for(var i in arrTmp){
console.log(i+":"+arrTmp[i])
}
//输出 0:value1 1:value2 2:value3 name:myTest

for…of遍历

(ES6语法,推荐使用) 不能用于遍历对象,详细见[Iterator 和 for…of 循环]

  • 可以正确响应break、continue和return语句
  • 改变原始数组
  • 只能读取键值item,如有需要可以使用索引index
    • 经典 for循环,foreach,array.entries(),array.keys()

数组的实例方法

entries(),keys()和 values(),经常和for…of 配合使用

它们都返回一个遍历器对象,可以用for…of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"

foreach 循环

  • 不响应break、continue和return
  • 没有返回值
  • 改变原数组
1
2
3
4
arr.forEach((item,index,array)=>{
//执行代码
})
//参数:item数组中的当前项, index当前项的索引, array原始数组;

map循环

映射,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

  • 不响应break、continue
  • 返回经过处理的新数组
  • 不改变原始数组
1
2
3
4
5
6
var ary = [12,23,24,42,1]; 
var res = ary.map(function (item,index,ary ) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化

filter循环

过滤,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。

  • 不响应break、continue
  • 返回经过处理的新数组
  • 不改变原始数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//示例功能,筛选偶数
const arr = [1,2,3,4,5,6,7,8]
const arrHandle1 = arr.filter(item => {
if(item%2===0){
return item
}
})
const arrHandle2 = arr.filter(item => {
if(item%2===0){
return item
}
return false
})
const arrHandle3 = arr.filter(item => {
if(item%2===0){
return true
}
return false
})
console.log(arrHandle1); [ 2, 4, 6, 8 ]
console.log(arrHandle2); [ 2, 4, 6, 8 ]
console.log(arrHandle3); [ 2, 4, 6, 8 ]

every

判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true

  • 不响应break、continue
  • 不改变原始数组
  • 返回Boolean
1
2
3
4
var arr = [1,2,3,1,6,4,6]
var brr = arr.every(item => item%2==0)
console.log(arr) //[1,2,3,1,6,4,6]
console.log(brr) //false

some

判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true

  • 不响应break、continue
  • 不改变原始数组
  • 返回Boolean
1
2
3
4
var arr = [1,2,3,1,6,4,6]
var brr = arr.some(item => item%2==0)
console.log(arr) //[1,2,3,1,6,4,6]
console.log(brr) //true

reduce.reduceRight

这两个方法都会迭代数 组的所有项,并在此基础上构建一个终返回值

数组的操作方法

改变原始数组的方法

  • pop(): 删除 array 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不改变数组,并返回 undefined 值。
    • 返回它删除的元素的值
  • push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
    • 返回修改后数组的长度
  • unshift(): 将参数添加到原数组开头,并返回数组的长度
    • 返回修改后数组长度
  • shift(): 数组的第一个元素从其中删除,并返回第一个元素的值,如果数组是空的,那么 shift() 方法将不进行任何操作,并返回 undefined 值。
    • 返回第一个元素的值
  • reverse(): 用于颠倒数组中元素的顺序。
    • 返回原数组
  • sort(): 排序,默认为升序排列,如果想按照其他标准进行排序,sort()方法是可以传入一个函数,函数通过返回一个值来决定
  • splice(): 功能强大的数组方法,向从数组中添加删除项目,然后返回被删除的项目
    • 返回被删除的项目
    • 语法 arrayObject.splice(index,howmany,item1,.....,itemX)
      • index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
      • howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
      • item1, …, itemX 可选。向数组添加的新项目。
  • copyWithin() 在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组
  • fill()
    • fill方法使用给定值,填充一个数组,fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
1
2
3
4
5
6
7
8
['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

不改变原始数组的方法

// TODO

  • join
  • toLocalString
  • toString
  • valueOf
  • slice
  • cancat
  • indexOf
  • lastIndexOf
  • includes
  • flat
  • flatMap
  • find
  • findIndex

类数组转换为数组

直接上代码

1
2
3
4
5
6
7
8
9
var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
// 1. slice
Array.prototype.slice.call(arrayLike); // ["name", "age", "sex"]
// 2. splice
Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"]
// 3. ES6 Array.from
Array.from(arrayLike); // ["name", "age", "sex"]
// 4. apply
Array.prototype.concat.apply([], arrayLike)

如果是有iterator接口的类数组,还可以用扩展运算符进行转换

1
[...NodeList]

其他方法

数组的方法详细见js高程第四版6.2 Array

克隆一个数组(浅拷贝),不会改变原始数组

  • concat()
    • array.concat()
  • slice() 另一个常用方法:Array.prototype.slice.call(arguments,0?)能将具有length属性的对象转成数组,功能类似于Array.from()
    • array.slice(0?)
  • Array.from() 将两类对象转为真正的数组:类似数组的对象(array-like object 有length属性就可以)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)
  • 扩展运算符 …
    • [...array]
  • Object.assign()
    • Object.assign([],arr)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let arr = [{ b: 1 },{ c: 1 },{ d: 1 },{ e: 1 }]
let brr = arr.concat([])
brr[0].b = 2
let crr = arr.slice()
crr[1].c = 2
let drr = [...arr]
drr[2].d = 2
let err = Object.assign([],arr)
err[3].e = 2
console.log(arr) //[{ b: 2 },{ c: 2 },{ d: 2 },{ e: 2 }]
console.log(brr) //[{ b: 2 },{ c: 2 },{ d: 2 },{ e: 2 }]
console.log(crr) //[{ b: 2 },{ c: 2 },{ d: 2 },{ e: 2 }]
console.log(drr) //[{ b: 2 },{ c: 2 },{ d: 2 },{ e: 2 }]
console.log(err) //[{ b: 2 },{ c: 2 },{ d: 2 },{ e: 2 }]