JavaScript数组使用详解,包含32种数组操作方法
前言
数组这种数据结构是我们在前端开发中使用最为频繁的数据结构之一,数组就是将多个元素(通常是一个类型)按一定的顺序排列放到一个集合中,那么这个集合我们就称之为数组,数组的每一项可以保存任何类型的数据。对于数组它的操作的方法也是有很多,所以在这里统一做一个总结,帮助自己加深印象,也希望能对其他小伙伴有个参考的价值。
数组的创建
- 字面量的形式创建数组
var arr = []
// []就是一个空数组,数据和数据之间用逗号隔开
- 在使用字面量表示法时,不会调用
Array
构造函数
- 构造函数
var arr1 = new Array()
- 可以给构造函数传递一个参数,如果传递的是
数值
,则会按照该数值创建包含给定项数
的数组;而如果传递的是其他类型
的参数,则会创建包含那个值的
只有一项的数组。
var colors = new Array(3) // 创建一个包含3项的数组
var names = new Array('Greg') // 创建一个包含1项,即字符串'Greg'的数组
- 在使用
Array
构造函数时也可以省略new
操作符,省略new
操作符的结果相同。
数组的使用
数组的检测:Array.isArray()
ECMAScript5新增了Array.isArray()
方法,这个方法的目的是最终确认某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。
if (Array.isArray(value)) {
// 对数组执行某些操作
}
转换方法:toString()、valueOf()
-
toString()
:返回由数组中每个值的字符串形式拼接
而成的一个以逗号分隔
的字符串。 -
valueOf()
:返回的还是数组本身。
增:arr.push()、array.unshift()
- 通过最大下标和数组的长度的关系来实现
arr[arr.length] = 'a'
-
arr.length
:数组的长度,它不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。 -
最大下标
:数组的长度-1,因为下标从0开始计算,长度从1开始计算。
- 往数组尾部增加数据
- 语法:
arr.push()
- 参数:需要添加的数据,可以是一个或者多个
- 返回值:新的数组的长度
- 往数组头部增加数据
- 语法:
array.unshift()
- 参数:需要添加的数据,可以是一个或者多个
- 返回值:新的数组的长度
删:array.pop()、array.shift()
- 从数组尾部删除数据
- 语法:
array.pop()
- 参数:没有
- 返回值:删除的那个元素
- 从数组头部删除数据
- 语法:
array.shift()
- 参数:没有
- 返回值:被删除的那个元素
改、查:中括号语法[]
- 在读取和设置数组的值时,要使用
中括号语法
,并提供相应值的基于0数字的索引。
var colors = ['a', 'b', 'c']
alert(colors[0]) // 显示第一项
colors[2] = 'd' // 修改第三项
colors[3] = 'e' // 新增第四项
数组转换成字符串:array.join()
- 语法:
array.join()
- 参数:连接符(默认以逗号相连)
- 返回值:连接好的字符串
数组的拼接:array.concat()
- 语法:
array.concat()
,将多个数组拼接成一个 数组(对原数组没有影响) - 参数:需要拼接的数组
- 返回值:拼接好的新数组
数组的翻转:array.reverse()
- 语法:
array.reverse()
,操作的是原数组
数组的提取:array.slice()
-
语法:
array.slice()
,从数组中提取子数组出来,返回的是一个提取出来的新数组,对原数组没有影响 -
参数:三种情况
- 不传参数,直接将原数组复制一份
- 一个参数
slice(begin)
,一个参数代表着从begin
(下标)一直到结束,包含结束 - 两个参数
slice(begin,end)
,从begin
开始到end
结束,但是不包含end
数组的查找元素:indexof()、lastIndexOf()
- 语法:
indexof()
,判断一个值是否在数组中,如果存在,返回该元素在数组的下标,如果不存在返回-1
- 参数:
- 需要判断的值
- 开始的下标,如果没有传递,默认是从0开始
- 返回值:该值在数组的下标或者
-1
-
lastIndexOf()
和indexof()
一样,只是从后面往前面查找
数组的删除、增加、替换:array.splice()
- 语法:
array.splice()
,可以实现数组的删除(任意位置删除)增加(任意位置增加)替换,操作的是原数组。 - 参数:
第一个参数:开始的下标
第二个参数:删除的个数
第三个参数:替换的元素
数组的排序:array.sort()
-
语法:
array.sort(function (a, b){ return a - b })
,操作的是原数组。 -
参数:函数,函数里面有两个形参a,b,就是两两之间要比较的数。函数返回值>0,则b会排在a的前面;函数返回值<0,则a会排在b的前面
-
小技巧:
return a-b
=> 从小到大,return b-a
=> 从大到小 -
返回值:排序好的数组
数组迭代方法
ECMAScript5为数组定义了5个迭代方法。 每个方法接受两个参数:要在
每一项运行的函数
和(可选的)运行该函数的作用域对象
——影响this的值。 传入这些方法中的函数会接收三个参数:数组项的值
、该项在数组中的位置
和数组对象本身
。
forEach()
- 作用:会遍历数组中的每一项,让每一项都会去执行这个
fn
,不会返回一个新数组
var arr = [1, 2, 3, 4]
var newArr = []
arr.forEach(function(item, index) {
newArr.push(item * item)
})
console.log(newArr)
- 好处:
- 不会造成全局变量的污染
- 可以直接使用箭头函数
map()
- 作用:也是遍历数组的每一项,执行对应的函数,将所有的函数的返回值,保存到一个新数组中
var arr = [1, 2, 3, 4]
var newArr = arr.map(function(item, index) {
return item * item
})
console.log(newArr)
filter()
- 作用:得到一个新数组,新数组中保留了所有满足过滤条件的值(
return true
的)。
var arr = [1, 3, 5, 7, 2, 4, 6, 8]
var newArr = arr.filter(function(item) {
// if (item % 2 === 1) {
// // 是奇数
// return true
// } else {
// return false
// }
return item % 2 === 1
})
console.log(newArr)
some()
- 作用:某一个,只要有一个满足了条件,返回了
true
,那么结果就是true
。
var arr = [1, 7, 8, 5, 10]
// 只要flag为 true, 就说明有偶数
var flag = arr.some(function(item) {
// if (item % 2 === 0) {
// return true
// }
// else {
// return false
// }
return item % 2 === 0
})
console.log(flag)
every()
- 作用:所有,每一个。必须每一个都满足条件,都返回
true
,那么结果才是true
。
var arr = [1, 3, 12, 7, 9]
var flag = arr.every(function(item) {
return item % 2 === 1
})
console.log(flag)
if (flag) {
console.log('都是奇数')
} else {
console.log('有偶数')
}
数组归并方法:reduce()、reduceRight()
reduce()
和reduceRight()
:这两个方法都会迭代数组的所有项,然后构建一个最终返回值。
-
不同点:其中
reduce()
方法从数组的第一项开始逐个遍历到最后。而reduceRight()
则从数组的最后一项开始,向前遍历到第一项。 -
方法参数: 参数一:在每一项上调用的函数
参数二:作为归并基础的初始值 -
函数参数: 参数一:前一个值
参数二:当前值
参数三:项的索引
参数四:数组对象
var values = [1, 2, 3, 4, 5]
var sum = values.reduce(function(prev, cur, index, array) {
return prev + cur
})
alert(sum) // 15
-
这个函数返回的任何值都会作为第一个参数自动传递给下一项。
-
第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项。
ES6
新增数组方法
Array.from()
- 作用:将两类对象转为真正的数组:
类似数组的对象
和可遍历的对象
。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
}
// ES5写法
var arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c']
// ES6写法
let arr2 = Array.from(arrayLike) // ['a', 'b', 'c']
- 只要是部署了Iterator接口的数据结构,
Array.from
都能将其专为数组。 - Array.from方法还支持类似数组的对象,所谓类似数组的对象,本质特征只有一点,
即必须拥有length属性
。而这种情况扩展运算符
无法转换。
Array.from({ length: 3 })
// [undefined, undefined, undefined]
-
Array.from
还可以接受第二个参数,作用类似于数组的map方法
,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x)
// 等同于
Array.from(arrayLike).map(x => x * x)
Array.from([1, 2, 3], x => x * x)
// [1, 4, 9]
- 如果map函数里面用到了
this关键字
,还可以传入Array.from
第三个参数,用来绑定this。
find()
- 作用:会返回第一个满足条件的元素(遍历过程中,只要有第一个函数
return true
,就找到该元素,并返回)。
const person = list.find(function(item, index) {
return item.id === 3
})
console.log(person)
findIndex()
- 作用:找到第一个满足条件的元素,返回该元素的下标。
const index = list.findIndex(function(item, index) {
return item.id === 3
})
console.log(index)
includes()
- 作用:返回一个布尔值,表示某个数组是否包含给定的值,与字符串的
includes
方法类似。
[1, 2, 3].includes(2) // true
- 该方法的第二个参数表示搜索的起始位置,默认为0.如果第二个参数为负数,则表示倒数位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
[1, 2, 3].includes(3, 3) // false
[1, 2, 3].includes(3, -1) // true
fill()
- 作用:使用给定值填充一个数组
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
- fill方法还可以接受第二和第三个参数,用于指定填充的起始位置和结束位置。
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', '7', 'c']
Array.of()
- 作用:用于将一组数值转换为数组。
Array.from(3, 11, 8) // [3, 11, 8]
Array.from(3) // [3]
Array.from(3).length // 1
copyWithin()
-
作用:在当前数组内部将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。操作的是原数组。
-
参数:
target
(必选):从该位置开始替换数据。start
(可选):从该位置开始读取数据,默认为0.如果为负数,表示倒数。end
(可选):到该位置前停止读取数据,默认等于数组的长度。如果为负数,表示倒数。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 倒数不是从0开始数
entries()、keys()、values()
- 作用:用于遍历数组。他们都返回一个遍历器对象,可用
for...of
循环遍历 - 区别:
keys()
是对键名
的遍历,values()
是对键值
的遍历,entries()
是对键值对
的遍历
for (let index of ['a', 'b'].keys()) {
console.log(index)
}
// 0
// 1
结语
本文内容是对自己在实际开发中的经验和对专业书籍学习所总结整理的,
如果对您有帮助,希望能给个????评论收藏三连!
欢迎关注互相交流,有问题可以评论留言。
参考资料
JavaScript高级程序设计
ES6标准入门