数组概述
- 数组是按次序排列的一组值,每个值的位置都有编号(从0开始)。任何类型的数据都可以放入数组。
var arr = [1, 2, 3];
var arr2 = [{a: 1,}, 'abc', true, 1, function(){}]
数组的本质
- 本质上数组属于一种特殊的
对象,typeof返回的类型是object。
var arr = ['a', 'b', 'c'];
Object.keys(arr); // ['0', '1', '2'] 数组的键名就是有序的一组整数
arr[0] // 'a' 键名被自动转为了数值
arr['0'] // 'a'
length属性
['a', 'b', 'c'].length // 3
var arr = [1, 2]
arr[5] = 6
arr // [1, 2, 空属性 × 3, 6]
arr[2] // undefined
arr.length // 6 数组的键可以不是连续的,length属性总是比最大键大1
arr.length = 1 // 修改length属性该数组会自动减少到length设置的值
arr // [1]
数组的遍历
var arr = [1,2,3]
for (const value of arr) {
console.log(value); // 1 2 3
}
// 不建议
for (const key in arr) {
console.log(key); // 0 1 2
}
数组建议用
for of循环,for in只能获取键名而且还是无序的。
for、while、do while、for in、 for of循环都可以使用break和continue。但使用return会报错,因为return只能在函数体中使用。- 数组的遍历方法不可以使用
break和continue,如果使用return则等价于for循环中的continue。
数组的空位
var a = [1, , 1]
a.length // 3 空位不影响数组的长度
var b = [1,2,]
b.length // 2 最后一个成员后面有一个逗号不会影响length属性
a[1] // undefined 读取空位返回undefined
var c = [1, 2, 3]
delete c[1] // true
c[1] // undefined 删除索引1的值这个位置就变成了空位
c.length // 3 length属性不受影响
类数组
- 如果一个对象的所有键名都是正整数或零,并且有
length属性,那么这个对象就被称作类数组。 arguments和DOM对象都是类数组。
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
obj[0] // 'a'
obj.length // 3
类数组本质是对象,不具备数组的方法。
类数组转为数组
- 类数组的
length属性和键名起始顺序如果有错误的话会导致数据出现问题。
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
Array.prototype.slice.call(obj); // ['a', 'b', 'c']
// 键名起始错误
var obj2 = {
1: 'a',
2: 'b',
3: 'c',
length: 3
}
Array.prototype.slice.call(obj2); // [空白, 'a', 'b']
// length属性为3,所以会转成length属性为3的数组。但由于类数组键名从1开始,所以数组0位就是空
// length属性错误
var obj2 = {
0: 'a',
1: 'b',
2: 'c',
length: 2
}
Array.prototype.slice.call(obj2); // ['a', 'b']
// length属性为2,所以会转成length属性为2的数组, 键名2的数据被舍弃。
slice()内部使用数组的length属性和下标进行遍历并返回一个新数组。恰巧类数组中这两个属性都有,所以才会返回一个新数组。