Array


Array.prototype.toString()
1
2
[1,2,3].toString() // '1,2,3'
[{}, {}].toString() // '[object, Object], [object, Object]'

创建数组

1、构造函数创建,传入一个数字参数,被认为是设置长度,传入2个以上参数,被初始化加入到数组中

1
2
3
4
5
var a1 = new Array(5);
console.log(a1.length);//5
console.log(a1); //[] ,数组是空的

var a2 = new Array(5,6); // 相当于a2 = [5, 6]

数组的索引与长度

1、数组的遍历: 数组也是对象,所以也可以使用for…in

1
for(let i in arr)

2、数组的长度:数组length是等于数组最大的index+1,当length变小时,数组会删除小于length的数据,当length变大时,只是往后面增加undefined的数据

1
2
3
4
5
6
7
var a = new Array(1,2,3);
a[100] = 100;
console.log(a.length); //101
console.log(a[99]); //undefined

a.length = 2
console.log(a);//[1,2]

数组的增删

1、增:直接使用索引(index不需要连续)
2、删:数组是特殊的对象,所以也可以使用删除对象的方法

1
2
var a = [1,2,3]
delete a[1] // 不过不会改变数组length,a[1] = undefined

3、使用栈方法:删除方法不能改变length,这是我们不愿看到的,pop和push可以实现先入后出

1
2
3
4
5
var a = [1,2,3]
let result = a.push(5); // result = 4,所以返回的是length长度
console.log(a) // [1,2,3,5]
let result 2 = a.pop() // result2 = 5,所以返回的是拿出的值,且pop里加参数是没意义的,它只拿出最后一个
console.log(a) // [1,2,3]

4、使用队列方法:也可以实现改变length,只是先入先出

1
2
3
4
let a = [1,2,3]
let result = a.unshift(6) // result = 4,返回的是length的长度
console.log(a) // [6,1,2,3]
let result1 = a.shift() // result1 = 6,返回的拿出的值,shift加参数没有意义

记忆方法:删除是返回删除的值,添加时返回length值,删除加参数是没有意义的
5、终极神器:splice: 3个参数:1:开始的索引,2:删除元素执行的次数,从索引开始算,3:输入新元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 删除
let a = [1,2,3,4]
let result = a.splice(1,2) // result = [2,3]
console.log(a) // [1,4]
// 特殊
var a = new Array()
a[2] = 2
a[3] = 3
a[7] = 4
a[8] = 5
console.log(a.splice(3,4)); //[3]
console.log(a); //[2: 2, 3: 4, 4: 5]
// 新增: 因为第二个参数是执行的次数,只要设为0就行了
var a = [1,2,3,4,5];
let result = a.splice(1,0,9,99,999); // result = []
console.log(a);//[1, 9, 99, 999, 2, 3, 4, 5]
// 模拟push
let arr1 = [1,2,3,4,5]
arr1.splice(arr1.length, 0, 6) // arr1 = [1,2,3,4,5,6]
// 模拟pop
let arr2 = [1,2,3,4,5]
arr2.splice(arr2.length-1, 1) // arr2 = [1,2,3,4]
// 模拟shift
let arr3 = [1,2,3,4,5]
arr3.splice(0, 1) // arr3 = [2,3,4,5]
// 模拟unshift
let arr4 = [1,2,3,4,5]
arr4.splice(0, 0, 1, 2) // arr4 = [1,2,1,2,3,4,5]

数组常用的api

不会修改原数组的api: join,slice,concat
会修改原数组的:reverse,sort
1、join

1
2
3
4
var a = [1,2,3,4,5];
console.log(a.join(',')); //1,2,3,4,5
console.log(a.join()); //1,2,3,4,5
console.log(a.join(' ')); //1 2 3 4 5

1.2、toString()

1
2
3
let a = [1,2,3]
a.toString() // '1,2,3'
console.log(a) / [1,2,3]

2、slice:取头不取尾

1
2
3
4
5
6
var a = [1,2,3,4,5];
console.log(a.slice(1)); // [2,3,4,5]
console.log(a.slice(1,2));//2
console.log(a.slice(1,-1));//[2, 3, 4]
console.log(a.slice(3,2));//[]
console.log(a); //[1, 2, 3, 4, 5]

3、concat:参数可以是数据和数组

1
2
3
4
5
var a = [1,2,3,4,5];
var b = [6,7,8,9];
console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(a); //[1, 2, 3, 4, 5]
console.log(a.concat(6,7)) // [1,2,3,4,5,6,7]

4、reverse

1
2
3
var a = [1,2,3,4,5];
a.reverse();
console.log(a); //[5, 4, 3, 2, 1]

5、sort: 对数组进行排序,可以传自定义的函数当参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var a=[5,4,3,2,1]
a.sort()
console.log(a) //[1, 2, 3, 4, 5]

//但是: 问题
var a=[7,8,9,10,11]
a.sort()
console.log(a) //[10, 11, 7, 8, 9]
因为按照字母表排序,7就比10大了,这时候我们需要传入自定义排序函数

// 解决方法
var a = [7,8,9,10,11]
a.sort(function(v1, v2){
if (v1 > v2) {
return 1
} else if (v1 < v2) {
return -1
}
})
// 当sort里的函数返回大于0时,v1要排在v2后面,当返回小于0时,v1要排在v2前面
// 所以可以简写为
a.sort(function(v1,v2){
return v1-v2
})
console.log(a) //[7, 8, 9, 10, 11]

var users = [{name: 'aaa', age: 21},{name: 'bbb', age: 18},{name: 'aba', age: 24}]
// 按age 从小到大排序
var sortByAge = users.sort(function(v1, v2){
return v1.age - v2.age
})
// 按name从大到小排序
var sortByName = users.sort(function(v1, v2){
return v2.name - v1.name
})

ES5新增api

6、Array.isArray(obj)

1
2
3
4
var a = [];
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false

7、.indexOf(element) / .lastIndexOf(element)
这两个方法用于查找数组内指定元素位置,查找到第一个后返回其索引,没有查找到返回-1,indexOf从头至尾搜索,lastIndexOf反向搜索。

1
2
3
var a = [1,2,3,3,2,1]
console.log(a.indexOf(2)) //1
console.log(a.lastIndexOf(2)) //4

8、.every(function(element, index, array)) / .some(function(element, index, array))
every是所有函数的每个回调函数都返回true的时候才会返回true,当遇到false的时候终止执行,返回false
some函数是“存在”有一个回调函数返回true的时候终止执行并返回true,否则返回false

1
2
3
4
5
6
7
var a = [1, 2, 3, 4, 5, 6]
console.log(a.every(function(e, i, arr){
return e < 5
}))
console.log(a.some(function(e,i,arr){
return e > 4
}))

9、.filter(function(element))

1
2
3
4
5
var a = [1, 2, 3, 4, 5, 6]
console.log(a.filter(function(e){
return e % 2 == 0;
})) // [2, 4, 6]
console.log(a) //[1, 2, 3, 4, 5, 6]

9.1、find(function(element, index, arr)):找到满足函数的第一个值,不改变数组,找不到返回undefined

1
2
3
4
let a = [1,2,3,4]
console.log(a.find(function(e, i){
return e % 2 === 0
}))

9.2、findIndex(function(element, index, arr)):找到满足函数的第一个值得位置,找不到返回-1

1
2
3
4
let a = [1,2,3,4]
console.log(a.findIndex(function(e, i){
return e % 2 === 0
}))

10、.reduce(function(accumulator, currentValue, currentIndex, arr), initValue)
/ .reduceRight(function(accumulator, currentValue, currentIndex, arr), value)
accumulator: 累计器,每次执行回调返回的累计值,最后输出
currentValue: 当前处理的元素
currentIndex: 当前处理元素的索引
arr: 调用reduce()的数组
initValue: 作为第一次调用回调的accmulator的值,没有就是数组中的第一个元素

1
2
3
4
5
6
7
// 数字数组
[1,2,3].reduce((accumulator, currentValue) => accumulator + currentValue) // 6
// 对象数组
let arr = [{x: 1}, {x: 2}, {x: 3}]
arr.reduce((accumulator, currentValue) => {
return accumulator + currentValue.x
}, 0) // 6

Es6 api

1、将类数组和string转化为真数组: Array.from():特别适合函数里的arguments和获取的nodeLists,任何有length属性的对象,Array.from()都可以变成真数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let str = 'str'
Array.from(str) // ['s','t','r']
Array.from(str, x=>x+i) // ['s0','t1','r2']
let obj = {0: 1, 1:2, 2: 3, length: 3} // length一定要存在,不然就是类数组了
Array.from(obj) // [1,2,3]
let ps = document.querySelector('p')
Array.from(ps).filter(item => {
return item.textContent.lenght > 100
})
function fn(){
arguments = Array.from(arguemnts)
arguments.push(6)
console.log(arguments)
}
fn(1,2,3) // [1,2,3,6]

2、创建数组:Array.of(),为了弥补Array()的不足

1
2
3
4
Array.of(2) // [2]
Array.of(1,2,3) // [1,2,3]
Array(2) // [,,]
Array(1,2) // [1,2]

3、填充:fill():第一个参数为填充值,第二个参数为填充起始位置,默认0,第三个参数为终止位置,默认length。填充包头不包尾

1
2
3
4
5
let arr = [1,2,3]
arr.fill(4) // [4,4,4]
console.log(arr) // [4,4,4]
arr.fill(5,1) // [4,5,5]
arr.fill(6,1,2) // [4,6,5]

4、匹配:includes(searchElement, fromIndex):查看searchElement是否和数组中的匹配,返回true或false,是为了弥补indexOf()的不足

1
2
3
4
5
6
let arr = [1,2,3]
arr.includes(1) // true
arr.includes(1,2) // false
// indexOf():判断是否是-1来判断是否存在,且不能区分NaN
[NaN].indexOf(NaN) // -1
[NaN].indexOf(NaN) // true

4.1匹配2:indexOf(searchElement, fromIndex): 查看searchElement是否和数组中的匹配,返回第一个匹配的位置,否则返回-1

1
2
3
4
let arr = [1,2,3,2]
arr.indexOf(2) // 1
arr.indexOf(2,2) // 3
arr.indexOf(1,2) // -1

4.2、匹配3: lastIndexOf(searchElement, fromIndex): 和indexOf差不多,只是返回最后一个匹配的值,是从最后往前搜索的第一个

1
2
3
4
let arr = [1,2,3,2]
arr.lastIndexOf(2) // 3
arr.lastIndexOf(2,2) // 1:注意不一样:因为被搜索的是[1,2,3]
arr.lastIndexOf(1,2) // -1

5、拉平数组:flat(Number):Number默认为1,不改变原数组

1
2
3
4
5
6
let arr = [1,2,[3,4],5]
arr.flat() // [1,2,3,4,5]
let arr1 = [1,2,[,3,[4,5]],6]
arr1.flat() // [1,2,3,[4,5],6]
arr1.flat(2) // [1,2,3,4,5,6] 拉平2层
arr1.flat(Infinity) // [1,2,3,4,5,6] 当不知道要拉平几层的时候

5.1、遍历数组后拉平,只能拉平一层:flatMap(function(elemnent, index, arr))

1
2
let arr = [1,2,3]
arr.flatMap(x => [x,x*2]) // [1,2,2,4,3,6] 实际[[1,2],[2,4],[3,6]].flat()

扩展运算符

1、 …

1
2
3
4
5
6
7
8
console.log(...[1,2,3]) // 1 2 3
主要用于函数调用
function add (x,y){
console.log(x+y)
}
add(...[1,2]) // 3
可以替换apply
function fn(x,y,z){console.log(x,y,z)}

Es5和Es6写法区别

1
2
3
4
5
6
7
8
9
10
11
12
13
Es5写法
let arg = [1,2,3]
fn.apply(null, arg)
Math.max.apply(null, [14, 3, 77])
Es6写法
fn(...arg)
Math.max(...[14, 3, 77])
Es5写法
let arr1 = [1,2,3]
let arr2 = [4,5,6]
Array.prototype.push.apply(arr1,arr2) // [1,2,3,4,5,6]
Es6写法
arr1.push(...arr2)

实际应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
拷贝数组
Es5
let a1 = [1,2,3]
let a2 = a1.concat()
Es6
let a2 = [...a1]
let [...a2] = a1
合并数组
ES5
let a1= [1,2,3]
let a2 = [2,3,4]
let a3 = a1.concat(a2)
ES6
let a3 = [...a1,...a2]
与解构赋值结合
let [first,...rest] = [1,2,3,4,5,6]
first // 1
rest // [2,3,4,5,6]
[first, ...rest] = [1]
first // 1
rest // []