陣列是記憶體中線性的連續資料,在JavaScript中,並沒有實際的陣列,而是以物件來模擬出相似的操作外觀。如果你要在JavaScript中建立所謂的陣列(以下還是先簡稱陣列),可以使用Array建構。例如:
js> var array1 = new Array();
js> array1.length;
0
js> var array2 = new Array(10);
js> array2.length;
10
js> var array3 = new Array(10, 20, 30);
js> array3.length;
3
js>
js> array1.length;
0
js> var array2 = new Array(10);
js> array2.length;
10
js> var array3 = new Array(10, 20, 30);
js> array3.length;
3
js>
上面示範了三種Array建構的方式,第一種方式建構出沒有任何元素的陣列,第二種方式建構出長度為10的陣列,每個索引位置(0到9)都是undefined,第三種方式則建構出內含三個元素的陣列,索引0開始分別是10、20、30。
實際上,很少人會直接使用Array建構陣列,而會使用陣列實字(Array literal)。例如:
js> var array1 = [];
js> array1.length;
0
js> var array2 = [];
js> array2.length = 10;
10
js> array2.length;
10
js> var array3 = [10, 20, 30];
js> array3.length;
3
js>
js> array1.length;
0
js> var array2 = [];
js> array2.length = 10;
10
js> array2.length;
10
js> var array3 = [10, 20, 30];
js> array3.length;
3
js>
你並沒有看錯,在JavaScript中,Array建立的實例,length特性是可讀可寫的。例如:
js> var array = [1, 2, 3];
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
3
js> array.length = 5;
5
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
3
undefined
undefined
js> array.length = 2;
2
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
js> array.length = 3;
3
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
undefined
js>
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
3
js> array.length = 5;
5
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
3
undefined
undefined
js> array.length = 2;
2
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
js> array.length = 3;
3
js> for(var i = 0; i < array.length; i++) {
> print(array[i]);
> }
1
2
undefined
js>
在上面的例子中,陣列原本的長度為3,後來設定length為5,索引3與4的部份沒有元素,所以是undefined,將length設為2時,原本索引2的資料就沒了,就算設回3也找不回來了。
陣列是記憶體中線性的連續資料,在JavaScript中,並沒有實際的陣列,而是以物件來模擬出相似的操作外觀,事實上,用Array建構出的物件,索引其實就是以代表數字的特性罷了,事實上索引指定方式也可以用字串,只要它代表數字:
js> var array = [1, 2, 3];
js> array['0'];
1
js> array['1'];
2
js> array['2'];
3
js> for(var i in array) {
> print(i);
> }
0
1
2
js> delete array[1];
true
js> array;
1,,3
js>
js> array['0'];
1
js> array['1'];
2
js> array['2'];
3
js> for(var i in array) {
> print(i);
> }
0
1
2
js> delete array[1];
true
js> array;
1,,3
js>
也因此,因為索引其實就是陣列物件上的特性,你也可以用delete刪除陣列中的元素,也因此,你可以輕易地使用普通物件,來模擬出陣列的操作外觀:
js> var obj = {
> '0' : 100,
> '1' : 200,
> '2' : 300,
> length : 3
> };
js> for(var i = 0; i < obj.length; i++) {
> print(obj[i]);
> }
100
200
300
js>
> '0' : 100,
> '1' : 200,
> '2' : 300,
> length : 3
> };
js> for(var i = 0; i < obj.length; i++) {
> print(obj[i]);
> }
100
200
300
js>
在JavaScript中如上模擬出所謂的陣列,是非常普遍的應用。那麼,建構Array實例,或者說使用陣列實字建構陣列的好處是什麼?當然是為了擁有Array已定義的行為,例如自動依元素內容來調整length:
js> var array = [];
js> array.length;
0
js> array[0] = 100;
100
js> array.length;
1
js> array[1] = 200;
200
js> array.length;
2
js> array[10] = 900;
900
js> array.length;
11
js>
js> array.length;
0
js> array[0] = 100;
100
js> array.length;
1
js> array[1] = 200;
200
js> array.length;
2
js> array[10] = 900;
900
js> array.length;
11
js>
陣列的長度隨時可以增加或減少,指定索引元素時也不一定要連續指定,例如上例中,直接指定了索引10為900,其它未指定的2到9索引處,全都是undefined(就像沒有2到9的特性名稱罷了),在JavaScript中,也沒有所謂陣列超出索引的問題,例如上例若指定array[10000],充其量就是傳回undefined。
直接使用Array實例來進行陣列操作,還可以獲得Array上已定義的方法。例如:
js> var array = [100, 200, 300];
js> array.forEach(function(element) {
> print(element);
> });
100
200
300
js>
js> array.forEach(function(element) {
> print(element);
> });
100
200
300
js>
forEach是Array所提供的方法,可以指定函式,陣列中每個元素會作為引數傳入函式,這是JavaScript風格的走訪陣列方式,在Array中,有很多這類接受函式的方法(關於傳入函式這類用法的說明,之後說明函式時還會談到)。
再來示範一下Array上的push()與pop():
js> var array = [];
js> array.push(100);
1
js> array.push(200);
2
js> array.push(300);
3
js> array;
100,200,300
js> array.pop();
300
js> array;
100,200
js> array.pop();
200
js> array;
100
js>
js> array.push(100);
1
js> array.push(200);
2
js> array.push(300);
3
js> array;
100,200,300
js> array.pop();
300
js> array;
100,200
js> array.pop();
200
js> array;
100
js>
更多陣列上的方法操作,可參考: