js数组

234 阅读4分钟

定义

数组的声明:

let array=['a','b','c']

每个数组都有自己的索引,从0开始,最终的索引为数组的长度-1。

在js中,数组其实是一种特殊的对象。对象是由键值对组成,每个键都是字符串。

数组是由索引、值组成,索引就是键,数组的键名就是由字符串'0','1'...组成的序列。只是索引被隐藏起来了,我们可以使用Object.key()返回数组的所有索引。

let array=['a','b','c']
Object.key(array)  // ["0", "1", "2"]

跟对象不太一样的是,数组没办法用.的形式读取,只能使用[]的形式来读取值。

let array=['a','b','c']
array.1 // Uncaught SyntaxError: Unexpected number
array[1] // "b"

中括号[]中的数字1会被解析成字符串读取。如果换成array['1']也是可以读取的。

length

数组的length属性返回成员数量

['a', 'b', 'c'].length // 3

每个数组都有length属性,这是不可变的,即使成员数量为0,那length就是0

数组的数字键不需要连续,length比最大的数字键大1

let arr=[]
arr[9] ='a'
arr // [empty × 9, "a"]
arr.length //10
arr[1] // undefined

越过前面的序列设置值时,前面的值都是empty,读取时返回undefined

length是可以人为修改的,如果人为设置比数组的实际成员数量小,则会缩减数组的成员数量

let arr=[1,2,3]
arr.length=2
arr //[1,2]

所以设置arr.length=0可以清空数组

当length设置比实际数组要大,那么会数组的成员数量会增加到这个值,读取时返回undefined

let arr=[]
arr.length=3
arr[1] //undefined

这里有个注意点:因为数组本质还是一个对象,可以设置其他键。如果设置它的键不为0、1、2...这样的字符串,那么不会增加length数量,这也说明length记录的是序列为0、1、2..的成员数量。

let arr=[]
arr['a']=1
arr[0]=2
arr.length // 1
arr //[2, a: 1]

in 运算符

因为数组是特殊的对象,所以自然可以使用in运算符来判断键是否存在于数组中

var arr = [ 'a', 'b', 'c' ];
2 in arr  // true
'2' in arr // true
4 in arr // false

上面的代码表明,由于键名都是字符串,所以数值2会自动转成字符串。

let arr=[];
arr[100]='a';
arr[0]=undefined
arr[1] //undefined 注意:这里的undefined只是返回,不代表这个位置上是undefined,实际它是empty,不信我们用in验证一下
`1` in arr //false 如果位置上是empty,则返回false
0 in arr //true 如果位置上是undefined 返回true

for...in 循环

for...in循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象。

var a = [1, 2, 3];

for (var i in a) {
  console.log(a[i]);
}
// 1
// 2
// 3

但是,for...in不仅会遍历数组所有的数字键,还会遍历非数字键。

var a = [1, 2, 3];
a.foo = true;

for (var key in a) {
  console.log(key);
}
// 0
// 1
// 2
// foo

所以我们推荐for in还是遍历对象吧,不建议遍历数组

数组遍历

数组的遍历可以考虑使用for循环或while循环。

var a = [1, 2, 3];

// for循环
for(var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

// while循环
var i = 0;
while (i < a.length) {
  console.log(a[i]);
  i++;
}

var y = a.length;
while (y--) {
  console.log(a[y]);
}

上面代码是三种遍历数组的写法。最后一种写法是逆向遍历,即从最后一个元素向第一个元素遍历。

逆向遍历还可以用于一道经典面试题,让数组取反。不过以上写法是我从阮一峰博客抄来的,非常不能理解,我改写了一下。

let a=[1,2,3]
let b=[]
var len=a.length
while(len){
console.log(len)
	b.push(a[len-1])
    len--
}
b //[3,2,1]

空位

let arr=[1,,3]
arr.length //3

上面的数组存在空位,但是不影响length属性

当读取时,返回的是undefined,这里要注意,空位读取时的undefined不代表空位上就是undefined,我们可以用in验证一下

let arr =[undefined,,undefined]
arr[1] //undefined
arr[0] //undefined
1 in arr //false
0 in arr //true

另外,使用delete也会产生空位,并且不影响length属性。

empty和数组上的值undefined是不一样的,使用时请注意。经过实验,empty无法被for inforEachObject.keys()获取到,但for循环除外。

let arr=[,,,]
Object.keys(arr) //[]

for(let k in arr){
	console.log(k)
	console.log(arr[k])
    } //没有东西
arr.forEach(function(v,i){console.log(v,i)}) //没东西