创建数组
ES5 及之前
数组的每一项都可以保存任何类型的数据,可以通过 Array
构造器和数组字面量语法两种方式创建数组,如果通过 Array
构造器创建数组,new
操作符可以省略。
1 | var a = new Array('red', 1); |
- 通过数组的 length 可以清空或截断数组。
- 数组会自动将字符串索引转换为对应数值索引,即
array['0'] === array[0]
。
Array 构造器的怪异点
通过 Array
构造器创建数组时,如果只传递一个数值,会创建一个有 length
属性的数组,但内部空空如也,无法进行如 forEach
等迭代操作。
1 | var normal = Array('3'); |
用 Array.apply 创建数组
1 | var a = Array.apply(null, { length: 3 }); |
通过解构&迭代器创建数组
1 | var a = [...Array(3).entries()]; |
Array.of
ES6 引入了 Array.of()
方法来解决 Array
构造器创建数组的怪异点。该方法的作用非常类似 Array
构造器,但在使用单个数值参数的时候并不会导致特殊结果。Array.of()
方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型。下面例子演示了 Array.of()
的用法:
1 | var a = Array.of(1, 2) |
Array.of()
方法并没有使用 Symbol.species
属性来决定返回值的类型,而是使用了当前的构造器(即 of()
方法内部的 this
)来做决定。例如,MyArray.of()
返回 MyArray
类型的实例,Array.of()
返回 Array
类型的实例。
Array.from
将可迭代对象或者类数组对象作为第一个参数传入,Array.from()
就能返回一个数组。这里有个简单的例子:
1 | function doSomething() { |
此处调用 Array.from()
方法,使用 arguments
对象创建了一个新数组 args
,它是一个数组实例,并且包含了 arguments
对象的所有项,同时还保持了项的顺序。
与 Array.of()
一样,Array.from()
方法同样使用当前的构造器(即 from()
方法内部的 this
)来决定要返回什么类型的数组。例如,MyArray.from()
返回 MyArray
类型的实例,Array.from()
返回 Array
类型的实例。
如果你想实行进一步的数组转换,你可以向 Array.from()
方法传递一个映射用的函数作为第二个参数。此函数会将类数组对象的每一个值转换为目标形式,并将其存储在目标数组的对应位置上。例如:
1 | function translate () { |
如果映射函数需要在对象上工作,你可以手动传递第三个参数给 Array.from()
方法,从而指定映射函数内部的 this
值。
1 | let helper = { |
只要一个对象有 length
属性,Array.from()
就会可以通过它得到对应长度的数组
1 | let a = { |
检测数组
ES5 提出了 Array.isArray()
方法来检测数组,不过并不是所有版本的浏览器都兼容这个方法。兼容各种情况的方法如下所示:
1 | function isArray (value) { |
转换方法
join()
接收一个字符串作为参数,然后以该字符串为分隔符将数组(或类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组中只有一个元素,那么将返回该元素的字符串形式而不使用分隔符。如果没有给join()
传递参数,则默认使用,
作为分隔符
1 | // "Fire,Air,Water" |
栈方法
栈是一种后进先出的数据结构,ECMAScript 为数组提供了 push()
和 pop()
方法来实现类似栈的行为。
push()
方法接收任意数量的参数,把他们逐个添加到数组末尾,然后返回修改后数组的长度.pop()
方法从数组末尾移除最后一项,将数组长度减 1,然后返回移除的项。
队列方法
队列的访问规则是先见先出,可以通过 unshift()
和 shift()
配合实现。
unshift()
方法在数组前端添加任意个项, 然后返回新数组的长度。shift()
方法移除数组中的第一项,将数组长度减 1,然后返回移除的项.
排序方法
reverse()
方法会反转数组项的顺序。sort()
方法默认按升序排列数组项,并且可以接收一个比较函数作为参数。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个参数之后则返回一个正数。
1 | var a = [1, 3, 2, 6] |
操作方法
concat
concat()
方法会创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。
如果传递的参数是一个或多个数组,则会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数组,这些值就会被简单的添加到结果数组的末尾。
1 | var colors = ['red', 'green', 'blue'] |
slice
slice(start, end)
方法返回一个由原数组索引从 start
到 end-1
的项组成的新数组。
- 如果省略
start
,则默认从 0 开始。 - 如果省略
end
或end
大于数组长度,则slice
方法会一直提取到数组末尾(包括最后一个元素) - 如果
start
或end
中有负数,则用数组长度加上该数来确定相应的索引。
1 | var colors = [1, 2, 3, 4] |
splice
splice(start, deleteNum, replaceItem, replaceItem, replaceItem, ...)
方法返回一个数组,该数组包含从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)。它是最灵活的一个数组操作方法,它可以实现对原始数组的删除、插入和替换操作。
start
:操作起始位置的索引。deleteNum
:要删除的项数。replaceItem
:要插入的项,一个或多个。
1 | var colors = ['red', 'green', 'blue'] |
fill
fill(value, start, end + 1)
方法使用参数 value
去替换数组索引从 start
至 end
的项。如果提供的起始位置(start
)或结束位置(end + 1
)为负数,则它们会被加上数组的长度来算出最终的位置。请观察下面的例子:
1 | let numbers = [1, 2, 3, 4] |
需要注意的是,fill()
方法是使用浅复制来完成的。
1 | let a = [1, 2]; |
copyWith
copyWithin()
方法与 fill()
类似,可以一次性修改数组的多个元素。不过,与 fill()
使用单个值来修改数组不同,copyWithin()
方法允许你在数组内部复制自身元素。为此你需要传递两个参数给 copyWithin()
方法:从什么位置开始进行修改,以及被用来复制的数据的起始位置索引。
1 | let numbers = [1, 2, 3, 4] |
默认情况下,copyWithin()
方法总是会一直复制到数组末尾,不过你还可以提供一个可选参数来限制到底有多少元素会被修改。这第三个参数指定了复制停止的位置(不包括该位置自身),这里有个范例:
1 | let numbers = [1, 2, 3, 4] |
类似于 fill()
方法,如果你向 copyWithin()
方法传递负数参数,数组的长度会自动被加到该参数的值上,以便算出正确的索引位置。
位置方法
indexOf(searchValue[, fromIndex])
和 lastIndexOf(searchValue[, fromIndex])
都是找到就返回索引,找不到就返回 -1。
迭代方法
every
arr.every(callback[, thisArg])
:对每个数组元素调用 callback()
方法,如果所有 callback()
的返回值都等价于 true
,返回 true
。否则返回 false
。
callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | var arr = [0, 1, 2]; |
some
arr.some(callback[, thisArg])
:对每个数组元素调用 callback()
方法,只要有一个 callback()
的返回值都等价于 true
,返回 true
。否则返回 false
。
callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | var arr = [0, 1, 2]; |
filter
arr.every(callback[, thisArg])
:对每个数组元素调用 callback()
方法,返回 callback()
返回值等价于 true
对应的元素所组成的新数组。
callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | var arr = [0, 1, 2]; |
forEach
arr.forEach(callback[, thisArg])
:对每个数组元素调用callback()
方法,该方法没有返回值。callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | var arr = [0, {}, {}]; |
map
arr.map(callback[, thisArg])
:对每个数组元素调用callback()
方法,返回所有callback()
返回值组成的新数组。callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | var arr = [0, {}, {}]; |
reduce
arr.reduce(callback[, initialValue])
:对每个数组元素调用callback()
方法,返回最后一个callback()
的返回值。callback(accumulator, currentValue[, index[, array]])
:该回调函数会在数组中进行迭代,它的返回值将传递给下一次迭代的accumulator
参数,它的参数介绍如下:accumulator
:上一次迭代的返回值。currentValue
:迭代的当前值。index
:当前索引。array
:数组对象。
initialValue
:作为callback()
进行第一次迭代时accumulator
的值。如果没有传入这个参数,那么callback()
在第一次迭代时会将数组的第一项作为accumulator
的值。
1 | var values = [1, 2, 3] |
reduceRight
arr.reduceRight(callback[, initialValue])
:按照倒序对每个数组元素调用callback()
方法,返回最后一个callback()
的返回值。callback(accumulator, currentValue[, index[, array]])
:该回调函数会在数组中进行迭代,它的返回值将传递给下一次迭代的accumulator
参数,它的参数介绍如下:accumulator
:上一次迭代的返回值。currentValue
:迭代的当前值。index
:当前索引。array
:数组对象。
initialValue
:作为callback()
进行第一次迭代时accumulator
的值。如果没有传入这个参数,那么callback()
在第一次迭代时会将数组的最后一项作为accumulator
的值。
1 | var values = [1, 2, 3] |
find
arr.find(callback[, thisArg])
:对每个数组元素调用callback()
方法,如果某一个callback()
返回值为true
,则返回其对应的数组元素。如果有多个callback()
都返回true
,则只返回第一个。如果所有callback()
都返回false
,则返回undefined
。callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | const a = [1, 2, 3]; |
findIndex
arr.find(callback[, thisArg])
:对每个数组元素调用callback()
方法,如果某一个callback()
返回值为true
,则返回其对应的索引。如果有多个callback()
都返回true
,则只返回第一个。如果所有callback()
都返回false
,则返回 -1`。callback(item, index, array)
:item
:元素。index
:元素对应索引。array
:arr
的引用。
thisArg
:作用域对象。
1 | const a = [1, 2, 3]; |