陣列

陣列是值的有序序列。有別於其他的語言,JavaScript 並沒有明確的陣列資料類型。取而代之,提供了 Array 物件,可以直接實體化或使用陣列的字面表達記法。

Array 物件有以各種方式操作陣列的方法,如合併、反轉、排序。他有一個用來指定陣列長度的屬性。JavaScript 也提供有用的陣列的字面表達語法,用來建立這些物件。

陣列的建立

陣列可以使用字面表達語法(通常是首選)或使用 Array 的建構子(也可以稱作函數,兩者行為完全相同)來建立︰

var colors = ["Red", "Green", "Blue"];

var colors = new Array("Red", "Green", "Blue");

var colors = Array("Red", "Green", "Blue");

陣列具有 length 屬性,提供來存取陣列的長度。如果你使用上述其中一個例子來初始化陣列,陣列的長度將會是 3︰

print(colors.length); // 3

在建立陣列的時候,如果你知道你的陣列的預期長度,你可以給 Array 的建構子傳入長度︰

var fiveItems = new Array(5);

明確定義長度並不會影響陣列的實際容量;這樣只會影響新陣列的 length 屬性。(陣列本身並沒有小於指定值的索引的屬性。)構建子的變體極少使用到。

JavaScript 1.7 引入陣列的簡約式作為建立新陣列的捷徑;下麵 會討論。

陣列元素的運用

你可以透過把值代入給陣列元素的方式儲存陣列。下麵是我們的範例 colors 陣列更為完整的實例︰

var colors = []; // 空陣列

print(colors.length); // 0

colors[0] = 'Red';

colors[1] = 'Green';

colors[2] = 'Blue';

print(colors.length); // 3

附加元素至陣列的末端的常見習慣是使用 array.length 作為索引︰

colors[colors.length] = 'Orange';

可以使用 array.push() 方法達到同樣效果︰

colors.push('Purple');

陣列的元素使用元素的索引來存取。陣列是以 0 開始索引,因此陣列中的第一個元素是 0︰

var red = colors[0];

可以使用各式各樣的陣列方法來存取陣列的元素。例如,pop() 方法移除並返回陣列的最後一個元素︰

var lastElement = colors.pop(); /* colors 的最後一個元素也被移除 */

理解 length

以實作的層級來說,JavaScript 的陣列實際上把元素存放成標準的物件屬性,並使用陣列的索引作為屬性的名稱。length 屬性很特別;他永遠會返回比保存在陣列中的最高索引值再高一的值︰

var cats = [];

cats[30] = ['Dusty'];

print(cats.length); // 31

你也可以把值代入給 length 屬性。寫下小於陣列中已存放的項目的數目,就會截掉其餘的項目;寫下 0 就完全清空陣列︰

var cats = ['Dusty', 'Misty', 'Twiggy'];

print(cats.length); // 3

cats.length = 2;

print(cats); // 輸出 "Dusty,Misty" - Twiggy 被移除了

cats.length = 0;

print(cats); // 什麼也沒輸出;cats 陣列是空的

反覆運算整個陣列

常見的操作就是反覆運算所有陣列的值,並以同樣方式處理每一個值。做到這一點的最簡單的方式如下︰

var colors = ['red', 'green', 'blue'];

for (var i = 0; i < colors.length; i++) {

alert(colors[i]);

}

如果你知道陣列中沒有一個元素會在布林的求值結果中為 false - 如果你的陣列只以 DOM 的結點組成,例如,你可以使用更有效率的習慣︰

var divs = document.getElementsByTagName('div');

for (var i = 0, div; div = divs[i]; i++) {

/* 以同樣方式處理 div */

}

這樣可以避免檢查陣列長度的開支,並且確保 div 變數被重新指定到每一次循環的使用中項目,以方便加入。

在 JavaScript 1.6引入 forEach

forEach 方法是在 JavaScript 1.6 引入的,提供了另一種反覆運算陣列的方式︰

var colors = ['red', 'green', 'blue'];

colors.forEach(function(color) {

alert(color);

});

傳給 forEach 的函數會在陣列中的每一個項目中執行一次,並把陣列的項目傳給函數作為參數。

在 JavaScript 1.6引入

某些 JavaScript 物件,如 document.getElementsByTagName 返回的 NodeList,或者在函數本體內部可以利用的 arguments 物件,表面上看來外觀和行為和陣列很類似,但並未共用所有的方法。例如,arguments 物件提供 length 屬性,但並未實作 forEach 方法。

在 JavaScript 1.6 中引入的通用陣列,為其他類似陣列的物件提供執行 Array 方法的途徑。每一個標準的陣列方法在 Array 物件本身都有相對應的方法;例如︰

function alertArguments() {

Array.forEach(arguments, function(item) {

alert(item);

});

}

這些通用方法可以在舊版本的 JavaScript 中,使用由 JavaScript 函數物件所提供的 call 方法,以更冗長的形式模擬。

Array.prototype.forEach.call(arguments, function(item) {

alert(item);

});

陣列的通用方法也可以使用在字串上,因為字串提供的對字元循序存取的方式,和陣列的很類似︰

Array.forEach("a string", function(char) {

alert(char);

});

二維陣列

下麵的代碼建立二維陣列。

var a = [];

for (i = 0; i < 4; i++) {

a[i] = [];

for (j = 0; j < 4; j++) {

a[i][j] = "[" + i + ", " + j + "]";

}

}

本例以如下的行來建立陣列︰

行 0: [0,0][0,1][0,2][0,3]

行 1: [1,0][1,1][1,2][1,3]

行 2: [2,0][2,1][2,2][2,3]

行 3: [3,0][3,1][3,2][3,3]

陣列的簡約式

在 JavaScript 1.7引入

在 JavaScript 1.7 中引入的陣列簡約式(array comprehension),對於以其他內容為基礎來建構新陣列提供了很有用的捷徑。簡約式通常可以用在 map() 和 filter() 呼叫的地方,或是結合這兩者的方式。

下麵的簡約式接收數字的陣列,並建立每一個數字的雙倍的新陣列。

var numbers = [1, 2, 3, 4];

var doubled = [i * 2 for each (i in numbers)];

alert(doubled); // 警報 2,4,6,8

這等同於下麵的 map() 操作︰

var doubled = numbers.map(function(i) { return i * 2; });

簡約式也可以用於選取符合特定表達式的項目。這是只選取偶數的簡約式︰

var numbers = [1, 2, 3, 21, 22, 30];

var evens = [i for each (i in numbers) if (i % 2 == 0)];

alert(evens); // 警報 2,22,30

filter() 也可以用於同樣的用途︰

var evens = numbers.filter(function(i) { return i % 2 == 0; });

map() 和 filter() 這類型的操作可以合併至單一的陣列簡約式。這是只篩出偶數的簡約式,然後建立內含雙倍數值的新陣列。

var numbers = [1, 2, 3, 21, 22, 30];

var doubledEvens = [i * 2 for each (i in numbers) if (i % 2 == 0)];

alert(doubledEvens); // 警報 4,44,60

陣列簡約式的方括號導入了默許的作用域區塊。新的變數(如範例中的 i)會被視為已經使用 let 宣告過了。其意義是不能在簡約式的外部使用這些變數。

輸入到陣列的簡約式本身並不需要是陣列;也可以使用 反覆運算器和產生器。