今日整理的是之前讀JavaScript 大全(e/6) 的筆記整理。
目前文字說明太多,打算再把一些觀念畫成圖來減少文字說明)~
這篇是陣列的讀取、寫入、長度、新增與刪除
用陣列來說,就是一組有編號且按照順序的集合。其中的值如下方的 a123
稱作為元素,元素在陣列中的位置是依照順序排序,陣列值所在的位置稱作 索引(index)。
JavaScript 陣列的元素可以是任何的資料型態,也可以將物件或其他陣列作為元素值。
陣列排序的 index
值從 0 (zero-based)開始,
let orderCode = ["a123","a124","a125","a126","a127","a128"];
// 排序的 index 值從 0 開始,陣列的元素有 6 個,index 從 0 到 5。
JavaScript 陣列可以根據需求增大或縮小,所以不用在建立陣列時就宣告陣列的大小, 或是在大小改變時重新配置 ( reallocate )。
陣列繼承屬性自 Array.prototype
,它定義了一組陣列操作方法,而這些方法大部分也可
以用在任何類似陣列(array-like)結構的物件上,比如字串的就像是一個一個字元的陣列(array of characters)。
let emptyCollection = []; // 沒有元素的空陣列
let numbers = [2,4,6,8,10]; // 5個數字元素的陣列
let ingredients = ["carrot", "potato", "pork", "onion", 5, false, 2.3]; // 4種不同資料型態的陣列元素
let yearsAgo = 2001;
let years = [yearsAgo, yearsAgo+3, yearsAgo+4, yearsAgo+6]; // 陣列也可以存放運算式
let objectAndNumbers = [[1, {x:1, y:2}], [2, {x:3, y:4}]];
Array()
建構式
let a = new Array(); // 建立空陣列,等於字面值 []
let b = new Array(5); // 指定陣列長度 5,但 index 的值 尚未定義
let c = new Array(5,6,8,7,1,"newArray, testing");
// 明確定指定陣列元素,或是指單一個非數值的元素,Array 建構子的引數就成為陣列的元素。
陣列中的元素不必然是連續的索引(index),其中可以有缺口(gaps)
JavaScript 陣列 的length 屬性, 對一般(非稀疏 nonsparse)陣列來說,這個屬性值代表陣列中所包含的元素數目
對稀疏陣列而言,length 比陣列中所有元素的索引(index)都還要大。
若陣列字面值中有多個逗號, 逗號間沒有值, 這個陣列是稀疏陣列,值被省略的陣列元素並不存在, 若你查詢的話,會得到 undefined
:
let countElement = [2,,4]; // 元素在 index 0 與 2之間。
console.log(countElement[1]); // undefined
let noneElement = [,,]; // 陣列沒有元素,不過它的長度會是2,JavaScript 陣列字面值( Array literal)可接受後面多出來的逗號,但長度是2。
使用
[]
運算子來存取陣列元素
let newArr = ["This world"]; // 建立一個新陣列,目前只有一個元素。
let value = newArr[0]
newArr[1] = 3.14; // 元素 2
let number = 2;
newArr[number + 1] = "Dream"; // 元素 3
newArr[newArr[number]] = newArr[0]; // 讀取元素 0 的值 指定給 元素3
用來存取陣列元素的[]
,和存取物件屬性的[]
一樣。 JavaScript 會把指定的數值陣列的 index 轉成字串, index 1 會變成 "1" ,然後會把就把 字串 index 值 當成物件的屬性名稱來用。
陣列可以使用 負數、非整數數字來存取陣列,因為這些數字會被轉成字串,用來做屬性名稱,這是被視為普通物件的屬性,而不是陣列的索引(index)。
若剛好使用的屬性名稱不是負整數的話,那麼會被視為陣列索引(index),不是物件的屬性,不是負整數的情況下,用浮點數也是會被視為陣列索引(index)。
newArr[-1.34] = true; // 建立了一個 "-1.34" 的屬性
newArr["1000"] = 0; // 會是此陣列第1001個元素
newArr[1.000] // 陣列的 index 會等於 1
JavaScript 陣列不會有 超出界限 out of bound 的錯誤(Error)的設計概念,只要物件的屬性不存在時,只會得到 undefined
,陣列也是相同。
let stars = null;
stars = [true, false] // index 0 與 1 各有元素 true 及 false
stars[3] // undefined 沒有這個元素
stars[-1] // undefined 沒有-1名稱的屬性
陣列有著 length(長度)的屬性,代表著元素的數目(非稀疏陣列的情況下),由於陣列的索引(index)值從0開始計算,所以length 長度的值就會比陣列最後的索引值加1。
console.log([].length); // 沒有元素, 長度是 0
console.log(["apple","orange","guava"].length); // 長度 = 3
在稀疏陣列中,length 屬性值會比元素數目大,目前可確定的是: 永遠不會有元素的索引值大於或等於陣列的長度。
有兩個設定是為了維持 元素不會為大於或等於陣列長度 的行為變化:
i
, 而 i
會大於或等於陣列的長度, 那麼 length 值會被設定為 i + 1
。
let recipe = ["eggplant", "basil", "chili", "garlic", "spring onion"]; // 5個字串元素
recipe.length = 3;
// 把 recipe 的元素數目(長度) 設定為3個,現在是["eggplant", "basil", "chili"]。
recipe.length = 0; // 陣列元素數目設定為0個,也就是刪除所有元素。 變回 recipe = []
recipe.length = 5; // 變回長度 = 5的陣列,但是裡面沒有元素了, 跟 new Array(5) 一樣
let tea = []; // 建立一個新的陣列
tea[0] = "green tea"; // 新增一個元素
tea[1] = "black tea";
// 使用陣列的push()方法在陣列最後面新增元素
tea.push("oolong tea"); // 在陣列最後面新增一個元素
console.log(tea); // [ 'Green tea', 'Black tea', 'Oolong tea' ]
tea.push("Pu-erh tea", "Osmanthus green tea");
// ['green tea','black tea','oolong tea','Pu-erh tea','Osmanthus green tea']
delete
let tea = []; // 建立一個新的陣列
tea[0] = "green tea"; // 新增一個元素
tea[1] = "black tea";
// 使用陣列的push()方法在陣列最後面新增元素
tea.push("oolong tea"); // 在陣列最後面新增一個元素
console.log(tea); // [ 'Green tea', 'Black tea', 'Oolong tea' ]
tea.push("Pu-erh tea", "Osmanthus green tea");
// ['green tea','black tea','oolong tea','Pu-erh tea','Osmanthus green tea']
delete
運算子刪除陣列元素,和刪除物件屬性一樣。使用 delete
運算子刪除陣列不會影響 length
屬性,被刪除的元素就像是指定 undefined
給此元素,且也不會重新把最大的索引值降低來填補陣列缺口,因此刪除元素會導致陣列變成稀疏陣列。delete tea[2];
console.log(tea);
// Array ["green tea", "black tea", undefined, "Pu-erh tea", "Osmanthus green tea"]
console.log(tea.length); // 5
pop()
方法(可和 push()
搭配使用),可以將陣列長度減 1 並回傳被刪除的元素的值。shift()
方法 (可和 unshift()
搭配使用): 從陣列開頭移除一個元素,並且會把所有元素移動到比索引值(index) - 1 的位置。splice()
在元素之間加入新元素、刪除或取代元素,所以也會影響到 length
屬性的增加或減少。 splice()
也可同時刪除或新增元素到陣列之中,新增或刪除的位置之後的元素索引(index)會增加或減少。
// MDN 引數說明
splice(start)
splice(start, deleteCount);
// 第一個引數指定加入或/和 刪除動作的開始位置, 第二個引數指定要從陣列中刪除多少個元素,如果第二個元素被省略,那麼從指定的位置開始到陣列最後的元素都會被刪除。 然後 splice()會回傳被刪除的元素所組成的陣列,如果元素沒有被刪除,就回傳`[]`空的陣列。
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)
// 前兩個引數是指定哪些元素要被刪除,後面的到 N 個引數是用來指定要加入陣列的元素,而加入的位置起始點由第一個引數來決定。
let coins = [1,2,3,4,5,6,7,8];
coins.splice(4); // return [5,6,7,8],
coins.splice(1,2); // return [2,3]
coins.splice(1,1); // return [4]
let usd = [1,2,3,4,5];
usd.splice(2,0,'x','y'); // return [], usd 為 [1,2,'x','y',3,4,5]