数组的实例属性和方法
实例属性
- length 数组中元素的个数, 需要注意的是,通过索引为数组赋值会改变数组的长度
let a = [ 1, 2 ]
console.log(a.length) // 2
a[1000] = 1
console.log(a.length) // 10001
实例方法
区分数组和Array
数组是调用Array后得到的对象实例,Array是该实例的构造函数
该实例的原型不是Array,而是Array.prototype,即对象实例的原型是该对象实例的构造函数的
prototype
属性
let a = []
a.__proto__ === Array.prototype // true
数组常用方法
数组的方法都是继承自原型对象——
Array.prototype
一般而言,为了降低编程的复杂度,倾向于使用
unmutable
(不可变)的方法,基于此,对数组的实例方法分类-
返回新数组的方法
- concat
合并多个数组,返回的新数组是对原始数组的浅拷贝
let e1 = { foo: 'foo' } let e2 = { bar: 'bar' } let a1 = [e1] let a2 = [e2] let a3 = a1.concat(e2) console.log(a3) // [{ foo: 'foo' }, { bar: 'bar' }] e1.foo = 'bar' console.log(a3) // [{ foo: 'bar' }, { bar: 'bar' }]
- entries
返回一个新的iterator对象。iterator
对象有一个next
方法,返回值为有value
和done
属性的对象,done
标识该
iterator
是否已经迭代完毕
let a = [1, 2, 3] let it = a.entries it.next() // { value: [0, 1], done: false } it.next() // { value: [1, 2], done: false } it.next() // { value: [2, 3], done: false } it.next() // { value: undefined, done: true }
- every
测试数组中是否所有元素都满足测试条件,参数为返回boolean
的测试函数
只要有一个元素不满足测试条件,该方法返回false,否则返回true。
对空数组([])调用会返回true
[1, 2, 3].every(function(e) { return e > 1 }) // false
- filter
筛选,参数为返回boolean
的测试函数,返回满足条件的元素组成的新数组,若没有满足条件的元素,则返回空数组
const a = [10, 5, 8] let b = a.every(function(e, index) { return e > 5 }) // [10, 8]
- find
查找,参数为返回boolean
的测试函数,返回第一个满足条件的元素,若没有满足条件的元素,则返回undefined
const a = [ { id: 1 }, { id: 2 }, { id: 3 } ] let b = a.every(function(e, index) { return e.id > 1 }) // { id: 2 }
- findIndex
查找下标,参数为返回boolean
的测试函数,返回第一个满足条件的元素的下标,若没有满足条件的元素,则返回-1
const a = [ { id: 1 }, { id: 2 }, { id: 3 } ] let b = a.every(function(e, index) { return e.id > 1 }) // 1
- flat
扁平化数组,参数为深度(默认为1),根据深度将所有元素及其子数组合并为一个新的数组。
使用Infinity
作为参数可以展开任意深度的嵌套数组
const a = [1, 2, [3, 4, [5, 6]]] a.flat(2) // [1, 2, 3, 4, 5, 6] a.flat(Infinity) // [1, 2, 3, 4, 5, 6]
- flatMap
映射+扁平化,参数为映射函数,即对映射后的中间数组调用flat(1)
const a = [1, 2, [3, 4, [5, 6]]] a.flatMap(function(e) { return e }) // [1, 2, 3, 4, [5, 6]]
- forEach
对每个元素执行一次映射函数,参数为映射函数
const a = [1, 2, 3] a.forEach(function(e) { console.log(e) }) // 1 // 2 // 3
- includes
测试一个数组是否包含指定元素,参数为待查找元素,可选的第二个参数为开始查找的下标,默认为0
检测-0 和 0,NaN 和 NaN会返回true
const a = [1, 2, 0, NaN] a.includes(2) // true a.includes(-0) // true a.includes(NaN) // true
- indexOf
查找一个给定元素的第一个索引,参数为待查找元素,若未找到,则返回-1
这里使用的是严格相等(类似===)
const a = [1, 2, 3] a.indexOf(2) // 1
- join
返回由参数连接符的数组元素组成的字符串,参数为连接符,默认为,
,对空数组返回空字符串
const a = [1, 2, 3] a.join('+') // "1+2+3"
- keys
返回包含数组中每个索引键的iterator
对象
const a = [1, 2, 3] const it = a.keys() it.next() // { value: 0, done: false } it.next() // { value: 1, done: false } it.next() // { value: 2, done: false } it.next() // { value: undefined, done: true }
lastIndexOf
与indexOf类似,区别是从后往前找map
根据映射函数,返回一个新数组,其中的元素是原数组中每个元素调用映射函数后的返回值
const a = [1, 2, 3] a.map(function(e) { return 2 * e }) // [2, 4, 6]
- reduce
对数组中的每个元素执行reduce
函数,将其结果返回成单个值,参数为reduce函数和初始值initialValue
, 第二个参数是可选的
reduce
函数的第一个参数是上一次调用reduce
函数的返回值,第二个参数是当前调用reduce
函数对应的数组元素
在第一次执行reduce
函数时,- 如果提供了
initialValue
,则reduce
函数的accumulator
值为initialValue
,currentValue
为第一个元素 - 如果没有提供
initialValue
,则reduce
函数的accumulator
值为数组的第一个元素,currentValue
为第二个元素 - 如果数组为空,且没有提供
initialValue
,则抛出异常
所以提供初始值是较好的做法
- 如果提供了
const a = [1, 2, 3] a.reduce(function(accumulator, currentValue) { return accumulator + currentValue }) // 6 a.reduce(function(accumulator, currentValue) { return accumulator + currentValue }, 10) // 16
reduceRight
同reduce类似,区别在于从右到左开始执行reduce函数-
slice
返回一个新的数组对象,长度由参数begin
和end
决定- 省略
begin
,则从0开始,若begin
为负数,如-2,则从倒数第2个元素开始 - 省略
end
,则默认为数组长度 - 若
end
在begin
的左边,则返回空数组
- 省略
[1, 2, 3].slice(1) // [2, 3] [1, 2, 3].slice(-1) // [3] [1, 2, 3].slice(1, 0) // []
- some
测试是否至少有一个元素满足测试函数,与every类似,区别在于只要有一个元素满足测试函数,就返回true
[1, 2, 3].some(function(e) { return e > 1 }) // true [1, 2, 3].every(function(e) { return e > 1 }) // true
- values
与keys类似,只不过迭代器的value为数组的元素,而不是下标
- concat
-
修改原数组的方法
- fill
使用固定的值填充数组,第一个参数是待填充的值,起始位置和结束位置是可选的
类似这种指明起始和结束位置的参数,不提供结束参数则默认到数组的length,并且不包括结束位置
[1, 2, 3].fill(4) // [4, 4, 4]
- pop
删除数组最后一个元素,并返回该元素,该方法会修改原数组的长度
[1, 2, 3].pop() // 3
- push
将一个或多个元素添加到数组的末尾, 返回数组的新长度
[1, 2, 3].push(4, 5, 7) // 6
- reverse
将一个数组中的元素反序
[1, 2, 3].reverse() // [3, 2, 1]
- shift
与pop类似,区别是删除数组中的第一个元素,并返回该元素
[1, 2, 3].shift() // 1
- sort
排序,可传入排序函数,默认会将元素转换成字符串再按照Unicode位点排序- 比较函数返回
-1,0,1
,表示小于,等于,大于
- 比较函数返回
[10, 200, 3, 9, 81].sort() // [10, 200, 3, 81, 9] [10, 200, 3, 9, 81].sort(function(e1, e2) { return e1 - e2 })
- splice
删除或替换现有元素或者原地添加新的元素来修改数组, 返回被删除元素组成的数组- 第一个参数
start
是操作开始的位置 - 第二个参数
deleteCount
为要删除元素的个数,若不指定,则删除从start
开始删除剩余所有元素,若小于等于零,则不删除 - 从第三个参数开始,为要添加的元素
- 第一个参数
let a = [1, 2, 3] a.splice(1) // 返回[2, 3] a = [1] a = [1, 2, 3] a.splice(1, 1) // 返回[2] a = [1, 3] a = [1, 2, 3] a.splice(1, 1, 11) // 返回[2] a = [1, 11, 3]
- unshift
将一个或多个元素添加到数组的开头,并返回该数组的新长度
let a = [1, 2, 3] a.unshift(4, 5) // 返回5 a = [4, 5, 1, 2, 3]
- fill