Javascript中多变的Array

Question

本着良好的编程习惯,定义了一个数组:

var mArray = new Array(2);

然后用array的push操作,打印数组就发现了问题:

mArray.push(1);
mArray.push(2);
console.log(mArray.length) //4
console.log(mArray) //[,,1,2]

原来贵语言如此的让人难以捉摸,一会再分析原因。首先说JavaScript中数组的几个特性:

多类型

JavaScript的数组支持多种数据类型混合,十分和谐,比如:

var mutiArray = [1,2,"go"];

动态扩容

所以初始化容量在JavaScript中是可选的

var incArray = [];
incArray[3] = 3;
console.log(incArray.length) //4

Stack & Queue ..

数组提供了丰富的方法,完全可以用数组来实现数据结构中常用的栈和队列。

var stack = new Array();
stack.push(1);
stack.push(2);
stack.push(3);
stack.pop();
console.log(stack);//[1,2]

var queue = new Array();
queue.push(1);
queue.push(2);
queue.shift();
console.log(queue);//[2]

当然这篇文章不是API,还有一些很实用的方法没有介绍到,比如slice,join等。

神奇的length

我们知道一般语言中的数组都有一个length属性,要么是通过array.length获得,要么是len(array),但是有一点是相同的,就是这个length是只读的。JavaScript这的Array.length偏偏就不是只读的,它还是可以修改的。。

比如将一个数组裁剪,控制为长度为20,就可以通过直接修改其length属性来实现,很凶残,当然也可以用同样语句对一个数组扩容。

if(someLongArray.length > 20){
    someLongArray.length = 29;
}

同样在进行栈的相关操作的时候,length也在不断的变化,当调用push的时候,length就+1,调用pop的时候,length就-1.

Solution

所以前面的问题就知道原因了

var mArray = new Array(2);

初始化了数组,length是2,然后每一次调用push长度都加一了。数组中前两个元素实际上是undefined

所以得到一个教训,若要使用JavaScript数组的Stack特性,就约束开发只使用相关的栈操作;同理适用于队列,也适用于只使用数组基本功能的情况。