1 # 直接宣告
JavaScript是弱型別語言,因此你可以直接將一個數組賦值給一個變數,即建立了一個數組:
let arr = [1, 2, 3];
絕大多數情況下使用的都會使用這種語法建立/宣告陣列。其中陣列使用中括號 [...]
包裹,元素之間用逗號 ,
分隔。
有時爲了程式碼優雅,遇到陣列元素很長很多時,也可以採用換行方式編寫:
let fruit - [ "apple", "banana", "orange", "..." ]
2 # 以物件方式建立陣列
這是建立陣列的另一種語法,即使用建構函式 Arrary()
:
let arr = new Array(); let arr = Array();
備註: 呼叫
Array()
時可以使用或不使用new
。兩者都會建立一個新的Array
例項。但出於程式設計規範,建議使用new
關鍵字。
用這種方式建立陣列是,裡面的引數有兩種使用情況:
1. 僅一個Number型別引數
let arr = new Array(6);
當只傳入一個 Number
型別 的引數時,傳入的引數則會被認定為是所建立陣列的長度,而非元素。且這個陣列僅有長度沒有任何元素,若訪問則是undefined
。
補充知識:
含空槽的陣列又被稱作為稀疏陣列。稀疏陣列在使用陣列迭代方法時,空槽元素都將被跳過。如果訪問空槽元素,結果會是
undefine
。
let arr = new Array(6); console.log(arr); // [ <6 empty items> ] console.log(arr[0]); // undefined console.log(arr.length); // 6
2. 有一個非Number型別引數 或 有多個引數
續上回,如只有一個引數但不是 Number
型別,則引數會被正常認定為是陣列的一個元素。
let arr = new Array("hello"); console.log(arr); // [ 'hello' ] console.log(arr[0]); // hello console.log(arr.length); // 1
有多個引數,則效果就如同使用[...]
宣告陣列一樣,所有引數都被視作陣列的元素。
let arr = new Array("hello", "world", "!"); console.log(arr); // [ 'hello', 'world', '!' ] console.log(arr.length); // 3
此種方式一般不會使用,不但有可能會引起一些誤會,也沒有中括號[...]
方式簡潔。
3 # 使用 Array.from()
方法建立
上面兩種建立陣列的基礎方式都無法建立一個初始化的陣列,這在一些情況下無法滿足我們的需求,例如建立雜湊陣列等等。這便是 Array.from()
能解決的第一個問題。
Array.from()
是一個全域性下的靜態方法,其作用是從可迭代或類陣列物件建立一個新的淺複製的陣列例項。不僅如此,還可以附帶一個對映函式為陣列內部的元素進行初始化操作。
首先我們先搞明白Array.from()
要求傳入的第一個引數 —— 一個 類陣列物件 或 可迭代物件。
1. 由類陣列物件建立陣列
該方法會根據類陣列物件建立一個長度為length
的陣列,其中的元素key
是合理下標值的元素。
什麼是類陣列物件?
顧名思義,就是形似陣列的物件。物件的屬性都含有
key
與value
,而這個關係也可以看作是陣列的下標與值的關係——key
為下標,value
為值。此外還有一個特別的key
是length
,用於表示陣列長度。類陣列物件還有個別名叫
arguments
物件。所以一個形似陣列的物件是:
let arguments = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 }
同時,這裏舉幾個用不符合規則的類陣列物件建立陣列的樣例:
長度與元素數量不符
元素數量會嚴格按照length
的值執行。如果沒有length
,則預設為0
——即一個空陣列。
let arguments = { 0: 1, 1: 2, 2: 3, length: 4 } let arr = Array.from(arguments); console.log(arr); // [1, 2, 3, undefined]
let arguments = { 0: 1, 1: 2, 2: 3, length: 0 } let arr = Array.from(arguments); console.log(arr); // []
鍵值不符合下標規範
如鍵值不符合下標規範,則這個鍵值對會被直接忽略。其它符合規則的鍵值對則被當作陣列元素。
let arguments = { 0: 1, 1: 2, 3: 3, length: 4 } let arr = Array.from(arguments); console.log(arr); // [1, 2, undefined]
2. 由可迭代物件建立陣列
除了從類陣列物件建立陣列,Array.from()
也可以從任何可迭代物件建立陣列。
什麼是可迭代物件?
可迭代物件是實現了
[Symbol.iterator]
方法的物件,這個方法返回一個迭代器。這個迭代器物件又具有next()
方法,每次呼叫next()
方法就會返回一個包含value
和done
屬性的物件,用於遍歷該可迭代物件。常見的內建可迭代物件有:
String
Array
TypedArray
(例如Uint8Array
)
NodeList
HTMLCollection
arguments
物件使用者自定義的可迭代物件
比如從String
建立陣列:
let str = 'hello'; let arr = Array.from(str); console.log(arr); // ["h", "e", "l", "l", "o"]
再比如從Set
建立陣列:
let set = new Set([1, 2, 3]); let arr = Array.from(set); console.log(arr); // [1, 2, 3]
3. 對映函式
除此之外,Array.from()
還可以接受第二個引數,作為一個對映函式,用於對每個元素進行處理後再放入新陣列,達到初始化的效果:
let set = new Set([1, 2, 3]); let arr = Array.from(set, x => x * x); console.log(arr); // [1, 4, 9]
這個對映函式類似於陣列的 map()
方法:
關於
map()
方法
map()
的作用是建立一個新陣列,其中每個元素都由原陣列中的每個元素都呼叫一次提供的函式後的返回值組成。
map()
包含兩個引數:
callbackFn
:為陣列中的每個元素執行的函式。它的返回值作為一個元素被新增為新陣列中。
thisArg
(可選):執行callbackFn
時用作this
的值。其中的
callbackFn
被呼叫時將傳入 3 個引數:
currentValue
: 正在處理的當前元素。
index
(可選): 正在處理的當前元素的索引。
array
(可選): 呼叫了map()
的陣列本身。
但是Array.from()
中的對映函式被呼叫時只傳入 2 個引數(element
、index
),不接受 map()
中callbackFn
的第三個引數array
。因為Array.from()
的執行過程中陣列仍然在構建。
除此之外,Array.from()
方法還接受第三個可選引數,這個引數被稱為"this 值",與map()
的thisArg
引數一致。
let person = { name: 'John', sayHello: function() { return `Hello, my name is ${this.name}`; } }; let nameArr = Array.from([1, 2, 3], function() { return this.sayHello(); }, person); console.log(nameArr); // ["Hello, my name is John", "Hello, my name is John", "Hello, my name is John"]
所以可以說Array.from(obj, mapFn, thisArg)
和 Array.from(obj).map(mapFn, thisArg)
會具有相同的結果。只是Array.from()
不會建立中間陣列,而是直接構建一個新陣列。
Array.from()
對映函式使用案例
初始化雜湊函式
let hash = Array.from({length: 26}, (item) => item = 0);
將字串轉換為大寫
let str = 'hello'; let arr = Array.from(str, (char) => char.toUpperCase()); console.log(arr); // ["H", "E", "L", "L", "O"]
平方陣列元素
let numbers = [1, 2, 3, 4, 5]; let squaredNumbers = Array.from(numbers, (x) => x * x); console.log(squaredNumbers); // [1, 4, 9, 16, 25]
獲取元素及其索引
let colors = ['red', 'green', 'blue']; let colorDetails = Array.from(colors, (color, index) => `${index}. ${color}`); console.log(colorDetails); // ["0. red", "1. green", "2. blue"]
使用箭頭函式作為對映函式
let set = new Set([1, 2, 3]); let doubledSet = Array.from(set, x => x * 2); console.log(doubledSet); // [2, 4, 6]
總結
在JavaScript中,建立陣列有 3 種主要方式,每種方式都有其獨特的特點和適用場景,選擇合適的陣列建立方式可以提高程式碼的可讀性和效能。
直接宣告
特點:語法簡潔、直觀,適用於大部分場景。
使用場景:適合絕大多數的陣列建立需求,尤其是需要建立包含已知元素的陣列。
案例:
let arr = [1, 2, 3]; let fruits = [ "apple", "banana", "orange", "..." ];
以物件方式建立陣列
特點:使用
Array()
建構函式,可以建立空陣列或指定長度的陣列。適用於一些特殊情況。使用場景:適合需要建立特定長度的空陣列或從單個非數字引數建立陣列的情況。
案例:
let arr = new Array(6); // 建立一個長度為6的空陣列 let singleElementArray = new Array("hello"); // 建立一個包含單個元素的陣列 let multipleElementsArray = new Array("hello", "world", "!"); // 建立一個包含多個元素的陣列
使用Array.from()
方法建立:
特點:從類陣列物件或可迭代物件建立陣列,同時可以使用對映函式對陣列元素進行初始化操作。
使用場景:適合從類陣列物件(如
arguments
物件)、可迭代物件(如Set
、String
)建立陣列,或需要對元素進行初始化操作時使用。案例:
// 從類陣列物件建立陣列 let arguments = { 0: 1, 1: 2, 2: 3, length: 4 }; let arr = Array.from(arguments); console.log(arr); // [1, 2, 3, undefined] // 從字串建立陣列 let str = 'hello'; let strArray = Array.from(str); console.log(strArray); // ["h", "e", "l", "l", "o"] // 使用對映函式 let numbers = [1, 2, 3, 4, 5]; let squaredNumbers = Array.from(numbers, x => x * x); console.log(squaredNumbers); // [1, 4, 9, 16, 25]