Tập hợp được lập chỉ mục là một cấu trúc dữ liệu, trong đó các phần tử được lưu trữ và
được truy cập bằng chỉ mục được đánh số. Những giá trị được lưu trữ trong một tập hợp đã lập chỉ mục là
gán chỉ mục được đánh số bắt đầu từ 0
, một mẫu có tên là "zero-indexing".
Sau đó, bạn có thể truy cập các giá trị được lưu trữ trong tập hợp được lập chỉ mục bằng cách tham chiếu
chỉ mục của chúng.
Mảng
Mảng là một vùng chứa có thể chứa 0 hoặc nhiều giá trị thuộc bất kỳ loại dữ liệu nào, bao gồm cả các đối tượng phức tạp hoặc các mảng khác. Các giá trị được lưu trữ trong một mảng là đôi khi được gọi là "phần tử" của mảng.
Tạo một mảng
Tương tự như với các kiểu dữ liệu gốc, có 2 cách tiếp cận để tạo mảng:
giá trị cố định của mảng hoặc bằng cách gọi hàm khởi tạo Array()
tích hợp sẵn của JavaScript
cùng với new Array()
. Việc chỉ định một mảng cho một biến mang lại khả năng linh động cao
và có thể lặp lại để chỉ định
nhiều giá trị thành một mã nhận dạng duy nhất.
Cú pháp giá trị cố định của mảng sử dụng một tập hợp dấu ngoặc ([]
) bao quanh số 0 hoặc nhiều hơn
giá trị dữ liệu được phân tách bằng dấu phẩy:
const myArray = [];
Cú pháp hàm khởi tạo mảng sử dụng đối tượng Array
tích hợp trong JavaScript làm
hàm khởi tạo có từ khoá new
:
const myArray = new Array();
Cả cú pháp giá trị cố định mảng và cú pháp hàm khởi tạo mảng đều cho phép bạn điền dữ liệu cho mảng khi thông tin đó được tạo, mặc dù các cú pháp có khác nhau một chút về cách các giá trị được xác định. Cú pháp ký tự mảng sử dụng các giá trị được phân tách bằng dấu phẩy giữa dấu ngoặc, giống như mảng thu được:
const myArray = [ true, null, "String", false ];
myArray;
> [ true, null, "String", false ]
Cú pháp hàm khởi tạo mảng lấy các giá trị được phân tách bằng dấu phẩy làm đối số, với một giá trị ngoại lệ hành vi đặc biệt:
const myArray = new Array( true, null, "String", false );
myArray;
> Array(4) [ true, null, "String", false ]
Khi một giá trị số được truyền đến hàm khởi tạo Array
, giá trị đó
không được gán cho vị trí thứ 0 trong mảng thu được. Thay vào đó, một mảng
sẽ được tạo bằng số chỗ trống cho các giá trị. Điều này không áp đặt bất kỳ
các giới hạn của mảng. Bạn có thể thêm và xoá các mục khỏi thư viện theo cách tương tự
giống như giá trị cố định mảng.
// Firefox:\
const myArray = new Array( 10 );
myArray;
> Array(10) [ <10 empty slots> ]
// Chrome:
const myArray = new Array( 10 );
myArray;
> (10) [empty × 10]
Mảng chứa các ô trống (đôi khi được gọi là "mảng thưa") là các mảng đặc biệt
trường hợp. Thay vì chứa giá trị undefined
hoặc null
rõ ràng, hãy để trống
vị trí thường, nhưng không phải lúc nào cũng được coi là giá trị undefined
ở nơi khác trong
ngôn ngữ.
Bạn có thể vô tình tạo một mảng thưa thớt bằng cú pháp giá trị cố định của mảng bằng cách bỏ qua một giá trị giữa dấu phẩy khi bạn tạo giá trị cố định mảng:
const myArray = [ true,, true, false ];
myArray;
> Array(4) [ true, <1 empty slot>, true, false ]
Mặc dù không được coi là một giá trị có ý nghĩa trong mọi ngữ cảnh, nhưng ô trống được tính vào tổng độ dài của mảng, có khả năng dẫn đến kết quả không mong muốn khi lặp lại qua các giá trị của mảng:
const myArray = [ 1,, 3, 4 ];
myArray.length;
> 4
for( const myValue of myArray ) {
console.log( myValue + 10 );
}
> 11
> NaN
> 13
> 14
Hành vi này là hạn chế so với một số quyết định thiết kế ban đầu của JavaScript. Tránh sử dụng các mảng thưa trong quá trình phát triển hiện đại.
Giống như giá trị gốc, giá trị cố định của mảng
kế thừa các thuộc tính và phương thức từ hàm khởi tạo tương ứng.
Do mảng là một dạng đặc biệt của đối tượng, nên cú pháp giá trị cố định của mảng và
Cú pháp new Array()
tạo ra các kết quả giống hệt nhau về chức năng: một đối tượng mà
kế thừa nguyên mẫu từ hàm khởi tạo Array
.
const arrayLiteral = [];
const arrayConstructor = new Array();
typeof arrayLiteral;
> "object"
arrayLiteral;
> Array []
length: 0
<prototype>: Array []
typeof arrayConstructor;
> "object"
arrayConstructor;
> Array []
length: 0
<prototype>: Array []
Vì hai kết quả giống hệt nhau và cú pháp giá trị cố định của mảng ngắn gọn hơn
và giá trị cố định, chúng tôi khuyên bạn nên luôn sử dụng cú pháp mảng giá trị thay vì
Cú pháp new Array()
.
Truy cập các giá trị mảng
Bạn có thể truy cập các phần tử riêng lẻ bên trong mảng bằng cách sử dụng ký hiệu dấu ngoặc, a
một cặp dấu ngoặc vuông ([]
) theo sau mảng hoặc giá trị nhận dạng của mảng đó có chứa
tham chiếu đến chỉ mục của phần tử đó:
[ "My string", "My other string" ][ 1 ];
> "My other string"
const myArray = [ "My string", 50, true ];
myArray[ 0 ];
> "My string"
myArray[ 1 ];
> 50
myArray[ 2 ];
> true
Các mảng trong JavaScript không liên kết, nghĩa là bạn không thể sử dụng một chuỗi tuỳ ý làm chỉ mục. Tuy nhiên, số liệu các giá trị dùng để truy cập vào các phần tử trong một mảng sẽ bị buộc thành một giá trị chuỗi cảnh, tức là bạn có thể sử dụng một giá trị chuỗi chỉ chứa số ký tự:
const myArray = [ "My string", 50, true ];
myArray[ 2 ];
> true
myArray[ "2" ];
> true
Việc cố gắng truy cập vào một phần tử bên ngoài những phần tử được xác định trong mảng sẽ dẫn đến
undefined
, không phải là lỗi:
const myArray = [ "My string", 50, true ];
myArray[ 9 ];
> undefined
Huỷ cấu trúc thao tác chỉ định
Giải cấu trúc gán là một cách ngắn gọn để trích xuất một phạm vi giá trị từ các mảng hoặc đối tượng và gán chúng vào một tập hợp mã nhận dạng, một quá trình đôi khi được gọi là "giải nén" cấu trúc dữ liệu gốc, mặc dù nó không sửa đổi mảng hoặc đối tượng gốc.
Quá trình gán huỷ cấu trúc sử dụng một danh sách giá trị nhận dạng giống mảng hoặc giống đối tượng để
theo dõi các giá trị. Ở hình thức đơn giản nhất, được gọi là mẫu liên kết
phá cấu trúc, mỗi giá trị sẽ được giải nén khỏi mảng hoặc đối tượng và được gán cho một
biến tương ứng, được khởi tạo bằng let
hoặc const
(hoặc var
):
const myArray = [ "A string", "A second string" ];
const [ myFirstElement, mySecondElement ] = myArray;
const myObject = { firstValue: false, secondValue: true };
const { myProp, mySecondProp } = myObject;
myFirstElement;
> "My string"
mySecondElement;
> "Second string"
myProp;
> false
mySecondProp;
> true
Dùng dấu ngoặc nhọn ({}
) để huỷ cấu trúc một đối tượng và dấu ngoặc vuông ([]
) để
huỷ cấu trúc một mảng.
const myArray = [ false, true ];
const myObject = { firstValue: false, secondValue: true };
const [ myProp, mySecondProp ] = myObject;
> Uncaught TypeError: myObject is not iterable
const { myElement, mySecondElement } = myArray;
myElement
> undefined
mySecondElement;
> undefined
Việc huỷ cấu trúc một mảng xảy ra theo trình tự, từ trái sang phải. Một mã nhận dạng tương ứng với phần tử của mảng có cùng chỉ mục:
const myArray = [ 1, 2, 3 ];
const [ myElement, mySecondElement, myThirdElement ] = myArray;
myElement;
> 1
mySecondElement;
> 2
myThirdElement;
> 3
Đây cũng là hành vi mặc định khi huỷ cấu trúc một đối tượng. Tuy nhiên, nếu các giá trị nhận dạng dùng trong quá trình gán gỡ lỗi khớp với các khoá của đối tượng thuộc tính, thì các giá trị nhận dạng đó được điền sẵn bằng thuộc tính tương ứng bất kể thứ tự chỉ định các giá trị đó:
const myObject = { firstValue: 1, secondValue: 2, thirdValue 3 };
const { secondValue, thirdValue, firstValue } = myObject;
firstValue;
> 1
secondValue;
> 2
thirdValue;
> 3
Bạn có thể bỏ qua các phần tử bằng cách bỏ qua giá trị nhận dạng:
const myArray = [ 1, 2, 3 ];
const [ firstValue,, secondValue ] = myArray;
firstValue;
> 1
secondValue;
> 3
Cú pháp phá cấu trúc cũng cho phép bạn gán giá trị mặc định trong trường hợp phá cấu trúc
giá trị là một ô trống, như trong trường hợp một mảng thưa thớt hoặc một
Giá trị undefined
.
const myArray = [ true, ];
const [ firstValue = "Default string.", secondValue = "Default string." ] = myArray;
firstValue;
> true
secondValue;
> "Default string."
Quá trình giải cấu trúc không ép buộc các giá trị vào các loại cụ thể. Điều này có nghĩa là
giá trị "falsy", chẳng hạn như trống
chuỗi (""
) hoặc null
, vẫn được coi là các giá trị được tách rời có ý nghĩa:
const myArray = [ false, null, 0, "",, undefined ];
const [ falseValue = true, nullValue = true, zeroValue = true, emptyStringValue = true, emptySlot = true, undefinedValue = true ] = myArray;
falseValue;
> false;
nullValue;
> null
zeroValue;
> 0
emptyStringValue;
> ""
emptySlot;
> true
undefinedValue;
> true
Toán tử trải rộng
Sử dụng toán tử trải rộng (...
), đã ra mắt trong ES6 để mở rộng dữ liệu có thể lặp lại
cấu trúc như mảng, chuỗi hoặc giá trị cố định đối tượng thành các phần tử riêng lẻ.
Toán tử phân tán đứng ngay trước cấu trúc dữ liệu cần mở rộng
hoặc giá trị nhận dạng của một biến chứa cấu trúc dữ liệu đó.
const myArray = [ 1, 2, 3 ];
console.log( ...myArray );
> 1 2 3
Cú pháp trải rộng dùng chủ yếu để sao chép và kết hợp các mảng:
const myArray = [ 4, 5, 6 ];
const mySecondArray = [1, 2, 3, ...myArray ];
mySecondArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]
Bạn chỉ có thể sử dụng cú pháp trải rộng trong các ngữ cảnh sau:
Đối với mảng và chuỗi, cú pháp trải rộng chỉ áp dụng khi không có hoặc nhiều đối số
trong lệnh gọi hàm hoặc các phần tử trong một mảng đều được dự kiến. Ví dụ đầu tiên về
trong phần này hoạt động vì nó truyền ...myArray
dưới dạng
một đối số cho phương thức console.log
tích hợp sẵn.
Ví dụ: bạn không thể chỉ định dữ liệu đang được trải rộng cho một biến bên ngoài một mảng khác:
const myArray = [ 1, 2, 3 ];
const spreadVariable = ...myArray;
> Uncaught SyntaxError: Unexpected token '...'
Nhưng bạn sao chép một mảng bằng cách trải rộng mảng ban đầu thành một giá trị cố định của mảng:
const myArray = [ 1, 2, 3 ];
const spreadArray = [ ...myArray ];
spreadArray;
> Array(3) [ 1, 2, 3 ]
Cách hợp nhất các phần tử tạo thành 2 hoặc nhiều mảng thành một mảng duy nhất:
const myArray = [ 1, 2, 3 ];
const mySecondArray = [ 4, 5, 6 ];
const myNewArray = [ ...myArray, ...mySecondArray ];
myNewArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]
Hoặc để truyền các phần tử của một mảng dưới dạng các đối số riêng lẻ trong lệnh gọi hàm:
const myArray = [ true, false ];
const myFunction = ( myArgument, mySecondArgument ) => {
console.log( myArgument, mySecondArgument );
};
myFunction( ...myArray );
> true false
Toán tử phân tán đã được mở rộng để tương thích với giá trị cố định của đối tượng trong ES2018. Tương tự như với mảng, bạn có thể sử dụng toán tử phân tán để sao chép hoặc hợp nhất đối tượng:
const myObj = { myProperty : true };
const mySecondObj = { ...myObj };
mySecondObj;
> Object { myProperty: true }
const myFirstObj = { myProperty : true };
const mySecondObj = { additionalProperty : true };
const myMergedObj = { ...myFirstObj, ...mySecondObj };
myMergedObj;
> Object { myProperty: true, additionalProperty: true }
Toán tử phân tán tạo ra "nông" sao chép. Điều này có nghĩa là tính năng này không sao chép nguyên mẫu của đối tượng gốc và không thể liệt kê các thuộc tính.
const myCustomPrototype = { protoProp: "My prototype." };
const myObj = Object.create( myCustomPrototype, {
myEnumerableProp: {
value: true,
enumerable: true
},
myNonEnumerableProp: {
value: false,
enumerable: false
}
});
const myNewObj = { ...myObj };
myObj;
> Object { myEnumerableProp: true, … }
myEnumerableProp: true
myNonEnumerableProp: false
<prototype>: Object { protoProp: "My prototype." }
myNewObj;
> Object { myEnumerableProp: true }
myEnumerableProp: true
<prototype>: Object { … }
Hãy nhớ rằng mảng và đối tượng không thể dùng thay thế cho nhau. Bạn không thể trải một đối tượng vào một mảng hoặc một mảng vào một đối tượng.
Nhân viên vận hành phần còn lại
Mặc dù cú pháp của chính toán tử đó giống nhau, nhưng toán tử còn lại (...
)
thực hiện chức năng ngược lại dựa trên ngữ cảnh sử dụng. Thay vì
mở rộng một cấu trúc dữ liệu có thể lặp lại thành các phần tử riêng lẻ, như trong
chỉ định phá cấu trúc hoặc dưới dạng một
tham số hàm, toán tử còn lại kết hợp
vào một cấu trúc dữ liệu có thể lặp lại. Tên này xuất phát từ thực tế
dùng để thu thập "những người còn lại" của một tập hợp các giá trị dữ liệu.
Khi được sử dụng cùng với thao tác gán huỷ cấu trúc, cú pháp được gọi là "thuộc tính còn lại" của bạn.
const myArray = [ "First", "Second", "Third", "Fourth", "Fifth" ];
[ myFirstElement, mySecondElement, ...remainingElements ] = myArray;
myFirstElement;
> "First"
mySecondElement;
> "Second"
remainingElements;
> Array(3) [ "Third", "Fourth", "Fifth"]
Khi dùng để cung cấp số lượng đối số vô hạn cho một hàm, cú pháp có tên là "thông số còn lại" cú pháp:
function myFunction( ...myParameters ) {
let result = 0;
myParameters.forEach( ( myParam ) => {
result += myParam;
});
return result;
};
myFunction( 2, 2 );
> 4
myFunction( 1, 1, 1, 10, 5 );
> 18
myFunction( 10, 11, 25 );
> 46
%TypedArray%
Mảng được nhập là một tính năng của ES6 được thiết kế để lưu trữ dữ liệu nhị phân có cấu trúc, dành cho chẳng hạn như khi làm việc với các tệp được tải lên hoặc WebGL.
Tương tự như với Symbols (Biểu tượng), %TypedArray%
hàm nội tại (thường được ghi nhận là %TypedArray%
hoặc @@TypedArray
để tránh bị nhầm lẫn với thuộc tính toàn cục) không phải là hàm khởi tạo trong
theo nghĩa thông thường và bạn không thể gọi nó bằng new
hoặc gọi nó trực tiếp.
Thay vào đó, %TypedArray%
đề cập đến một lớp cấp cao mẹ của cá nhân
hàm dựng, mỗi hàm khởi tạo hoạt động với một định dạng dữ liệu nhị phân cụ thể. Chiến lược phát hành đĩa đơn
lớp cấp cao %TypedArray%
nội tại cung cấp các thuộc tính và phương thức tiện ích
tất cả lớp con hàm khởi tạo %TypedArray%
và thực thể của lớp đó sẽ kế thừa.
Kiểm tra kiến thức
Cho `const myArray = [ 30, 50, 70 ];` `myArray[1]` có nghĩa là gì quay lại?
70
Nếu `myArray` có 3 giá trị, `myArray[9]` trả về giá trị gì?
9
Null
Undefined