javascript數組特性
數組是一段線性分配的內存, 它通過整數計算偏移並訪問其中的元素. 數組是一種性能出色的數據結構.
1.數組字面量
數組字面量提供了一種非常方便地創建新數組的表示法. 多個用逗號分隔的值的表達式. 數組字面量允許出現在任何表達式可以出現的地方. 數組的第一個值將獲得屬性名‘0‘, 第二個值將獲得屬性名‘1‘, 以此類推:
1 var empty = [];
2 var numbers = [
3 ‘zero‘, ‘one‘, ‘two‘, ‘three‘, ‘four‘,
4 ‘five‘, ‘six‘, ‘seven‘, ‘eight‘, ‘nine‘
5 ];
6
7 console.log(empty[1]); // undefined
8 console.log(numbers[1]);// ‘one‘
9
10 console.log(empty.length);// 0
11 console.log(numbers.length);// 10
對象字面量:
1 var numbers_object = {
2 ‘0‘: ‘zero‘,
3 ‘1‘: ‘one‘,
4 ‘2‘: ‘two‘,
5 ‘3‘: ‘three‘,
6 ‘4‘: ‘four‘,
7 ‘5‘: ‘five‘,
8 ‘6‘: ‘six‘,
9 ‘7‘: ‘serven‘,
10 ‘8‘: ‘eight‘,
11 ‘9‘: ‘nine‘
12 };
兩者產生的結果相似, numbers和numbers_object都是包含10個屬性的對象, 並且那些屬性剛好有相同的名字和值. 但是他們也有一些顯著的不同, numbers繼承自Array.prototype, 而numbers_object繼承自Object.prototype, 所以numbers繼承了大量有用的方法. 同時, numbers也有一個詭異的length屬性, 而numbers_object則沒有.
在大多數語言中, 一個數組所有元素都要求是相同的類型. JavaScript允許數組裏包含任意混合類型的值:
1 var misc = [
2 ‘string‘, 98.6, true, false, null, undefined,
3 [‘nested‘, ‘array‘], {object: true}, NaN,
4 Infinity
5 ];
6
7 console.log(misc.length);// 10
在JavaScript中, 中括號[]表示一個數組, 也可以理解為數組對象; 花括號{}表示一個對象, []和{}一起使用, 可以形成一個對象數組, 如以上示例所示.
2.長度
每個數字都有一個length屬性, 和大多數其他語言不同, JavaScript數組的length是沒有上界的. 如果你用大於或等於當前length的數字作為下標來存儲一個元素, 那麽length值會被增大以容納新元素, 不會發生數組越界錯誤.
length屬性的值是這個數組的最大整數屬性名加上1, 它不一定等於數組裏的屬性的個數:
1 var myArray = [];
2 console.log(myArray.length);// 0
3
4 myArray[1000000] = true;
5 console.log(myArray.length);// 10000001
6 // myArray只包含一個屬性
[]後置下標運算符把它所含的表達式轉換成一個字符串, 如果該表達式有toString方法, 就使用該方法的值. 這個字符串被將用作屬性名. 如果這個字符串看起來像一個大於等於這個這個數組當前的length且小於4294967295的正整數, 那麽這個數組的length會被重新設置為新的下標加1, 否則length值為這個數組的長度.
3.刪除
由於JavaScript的數組其實就是對象, 所以delete運算符可以用來從數組中移除元素:
1 var numbers = [‘zero‘, ‘noe‘, undefined, ‘shi‘, ‘go‘];
2 delete numbers[2];
3 console.log(numbers.length);// 5
不幸的是, 那樣會在數組中留下一個空間. 這是因為排在被刪除元素之後的元素保留著它們最初的屬性. 而你通常想要的是遞減後面每個元素的屬性.
幸運的是, JavaScript數組有一個splice方法. 它可以對數組做個手術, 刪除一些元素並將它們替換為其他的元素. 第1個參數是數組中的一個序號, 第2個參數是要刪除的元素個數. 任何額外的參數會在序號那個點的位置被插入到數組中:
1 var numbers = [‘zero‘, ‘noe‘, undefined, ‘shi‘, ‘go‘];
2 numbers.splice(2, 1);
3 console.log(numbers.length);// 4
值為‘shi‘的屬性的鍵值從‘3‘變到‘2‘. 因為被刪除屬性後面的每個屬性必須被移除, 並且以一個新的鍵值重新插入, 這對於大型數組來說可能會效率不高.
4.容易混淆的地方
在JavaScript編程中, 一個常見的錯誤是在必須使用數組時使用了對象, 或者在必須使用對象時使用了數組. 其實規則很簡單: 當屬性名是小而連續的整數時, 你應該使用數組. 否則, 使用對象.
JavaScript本身對於數組和對象的區別是混亂的. typeof運算符報告數組的類型是‘object‘, 這沒有任何意義, JavaScript沒有一個好的機制來區別數組和對象, 我們可以通過定義自己的is_array函數來彌補這個缺陷:
1 var array = [
2 ‘zero‘, ‘one‘
3 ];
4
5 var obj = {
6 ‘0‘: ‘zero‘,
7 ‘1‘: ‘one‘
8 };
9
10 var is_array = function (value) {
11 return Object.prototype.toString.apply(value) === ‘[object Array]‘;
12 };
13
14 console.log(is_array(array));// true
15 console.log(is_array(obj));// false
5.方法
JavaScript提供了一套數組可用的方法. 這些方法是被儲存在Array.prototype中的函數, Object.prototype和Array.prototype是可以被擴充的, 舉例來說, 假設我們想要給array增加一個方法, 它允許我們隊數組進行計算:
1 //通過給Function.prototype增加方法來使得該方法對所有函數可用
2 Function.prototype.method = function (name, func) {
3 this.prototype[name] = func;
4 return this;
5 };
6
7 Array.method(‘reduce‘, function (f, value) {
8 var i;
9 for (i = 0; i < this.length; i++) {
10 value = f(this[i], value);
11 }
12 return value;
13 });
通過給Array.prototype擴充了一個函數, 每個數組都繼承了這個方法. 在這個例子裏, 我們定義了一個reduce方法, 它接受一個函數和一個初始值作為參數,. 它便利這個數組, 以當前元素和該初始值為參數調用這個函數, 並且計算出一個新值. 當完成時, 它返回這個新值.
如果我們傳入一個把兩個數字相加的函數, 它會計算出相加的和. 如果我們傳入把兩個數組相乘的函數, 它會計算兩者的乘積:
1 // 創建一個數組數組
2 var data = [4, 8, 15, 16, 23, 42];
3
4 // 定義兩個簡單的函數, 一個是把兩個數字相加, 另一個是把兩個數字相乘.
5 var add = function (a, b) {
6 return a + b;
7 };
8
9 var mult = function (a, b) {
10 return a * b;
11 };
12
13 // 調用data的reduce方法, 傳入add函數.
14 var sum = data.reduce(add, 0);
15 console.log(sum);// 108
16
17 // 再次調用reduce方法, 這次傳入mult函數
18 var product = data.reduce(mult, 1);
19 console.log(product);// 7418880
20
21 // 因為數組其實就是對象, 所以我們可以直接給一個單獨的數組添加方法:
22 data.total = function () {
23 return this.reduce(add, 0);
24 };
25
26 console.log(data.total());// 108
6.指定初始值
JavaScript的數組通常不會預置值. 如果你用[]得到一個新數組, 它將是空的. 如果你訪問一個不存在的元素, 得到的值則是undefined. 如果你知道這個問題, 或者你在嘗試獲取每個元素之前都很有預見性地設置他的值, 那就萬事大吉了. 但是, 如果你實現的算法是假設每個元素都從一個已知的值開始(例如0), 那麽你必須自己準備好這個數組. JavaScript應該提供一些類似Array.dim這樣的方法來做這件事情, 但我們可以很容易糾正這個疏忽:
1 Array.dim = function (dimension, initial) {
2 var a = [], i;
3 for (i = 0; i < dimension; i++) {
4 a[i] = initial;
5 }
6 return a;
7 };
8
9 // 創建一個包含10個0的數組
10 var myArray = Array.dim(10, 0);
JavaScript沒有多維數組, 但就像大多數類C語言一樣, 它支持元素為數組的數組:
1 var matrix = [
2 [0, 1, 2],
3 [3, 4, 5],
4 [6, 7, 8]
5 ];
6
7 console.log(matrix[2] [1]);// 7
JavaScript對矩陣也提供了更好的支持:
1 Array.matrix = function (m, n, initial) {
2 var a, i, j, mat = [];
3 for (i = 0; i < m; i++) {
4 a = [];
5 for (j = 0; j < n; j++) {
6 a[j] = initial;
7 }
8 mat[i] = a;
9 }
10 return mat;
11 };
12
13 // 構造一個用0填充的4 * 4矩陣
14 var myMatrix = Array.matrix(4, 4, 0);
15 console.log(myMatrix);
16 console.log(myMatrix[3] [3]);// 0
用0填充的4 * 4矩陣:
1 // 用來構造一個單位矩陣的方法
2 Array.identity = function (n) {
3 var i, mat = Array.matrix(n, n, 0);
4 for (i = 0; i < n; i++) {
5 mat[i] [i] = 1;
6 }
7 return mat;
8 };
9
10 myMatrix = Array.identity(4);
11 console.log(myMatrix);
12
13 console.log(myMatrix[3] [3]);// 1
單位矩陣:
javascript數組特性