--- title: Keyed collections slug: Web/JavaScript/Guide/Keyed_collections translation_of: Web/JavaScript/Guide/Keyed_collections ---
Chương này sẽ giới thiệu về bộ sưu tập dữ liệu được sắp xếp theo key; Map
và Set
objects chứa các phần tử có thể được lặp lại theo thứ tự được thêm vào.
ECMAScript 2015 giới thiệu một cấu trúc dữ liệu mới để ánh xạ giá trị thành giá trị. Một đối tượng {{jsxref("Map")}} là một ánh xạ đơn giản key/value và có thể lặp lại các phần tử theo thứ tự thêm vào.
Đoạn code bên dưới sẽ thể hiện các thao tác cơ bản với Map
. Xem thêm {{jsxref("Map")}} để có thêm nhiều ví dụ và toàn bộ API. Bạn có thể sử dụng một vòng lặp {{jsxref("Statements/for...of","for...of")}} để trả về một mảng của [key, value]
trong mỗi lần lặp.
let sayings = new Map(); sayings.set('dog', 'woof'); sayings.set('cat', 'meow'); sayings.set('elephant', 'toot'); sayings.size; // 3 sayings.get('fox'); // undefined sayings.has('bird'); // false sayings.delete('dog'); sayings.has('dog'); // false for (let [key, value] of sayings) { console.log(key + ' goes ' + value); } // "cat goes meow" // "elephant goes toot" sayings.clear(); sayings.size; // 0
Thông thường, {{jsxref("Object", "objects", "", 1)}} được sử dụng để ánh xạ string thành value. Objects cũng cho phép bạn đặt key thành values, truy xuất các value, xóa các key, và kiểm tra xe có dữ liệu nào được lưu trữ trong một key. Tuy nhiên Map
objects có một vài lợi thế hơn giúp chúng tốt hơn trong việc ánh xạ.
Object
là {{jsxref("Global_Objects/String","Strings")}} hoặc {{jsxref("Global_Objects/Symbol","Symbols")}}, trong khi chúng có thể là bất kỳ giá trị nào trong một Map
.size
của một Map
dễ dàng, trong khi bạn sẽ phải xử lý thủ công để lấy được kích thước của một Object
.Object
có một prototype, vì thế có các giá trị mặc định của key trong ánh xạ. (Điều này có thể bỏ qua bằng cách sử dụng map = Object.create(null)
.)Ba mẹo dưới đây có thể giúp bạn quyết định khi nào thì sử dụng Map
hoặc Object
:
Đối tượng {{jsxref("WeakMap")}} là một bộ sưu tập của cặp key/value trong đó các key chỉ là các đối tượng và các value có thể là bất kỳ giá trị nào. Tham chiếu đối tượng trong các key được giữ yếu ớt (weakly), có nghĩa là chúng là mục tiêu của garbage collection (GC) nếu không có tham chiếu nào khác đến đối tượng nữa. Các WeakMap
API giống với các Map
API.
Một điểm khác biệt so với các Map
objects là các key của WeakMap
không đếm được (tức là không có phương thức nào cung cấp cho bạn danh sách các key). Nếu có, danh sách key sẽ phụ thuộc vào trạng thái của garbage collection, đưa ra tính không xác định.
Một số thông tin và ví dụ khác, xem tại "Why WeakMap?" trong tài liệu tham khảo {{jsxref("WeakMap")}}.
Một trường hợp sử dụng các WeakMap
objec là lưu trữ dữ liệu riêng tư cho một đối tượng hoặc ấn chi tiết thực hiện. Ví dụ sau đây từ bài đăng trên blog của Nick Fitzgerald's "Hiding Implementation Details with ECMAScript 6 WeakMaps". Các dữ liệu và phương thức riêng bên trong object sẽ được lưu trữ trong đối tượng privates
. Tất cả các instance và prototype lộ ra được công khai; mọi thứ khác không thể truy cập từ bên ngoài bởi vì privates
không được xuất từ mô-đun.
const privates = new WeakMap(); function Public() { const me = { // Private data goes here }; privates.set(this, me); } Public.prototype.method = function () { const me = privates.get(this); // Do stuff with private data in `me`... }; module.exports = Public;
Các {{jsxref("Set")}} object là bộ sưu tập các giá trị. Bạn có thể lặp các phần tử theo thứ tự được thêm vào. Một giá trị trong một Set
chỉ có thể xuất hiện một lần; nó là duy nhất trong Set
.
Đoạn code dưới đây là các thao tác cơ bản với Set
. Xem thêm tại tài liệu tham khảo {{jsxref("Set")}} để có thêm nhiều ví dụ và toàn bộ các API.
let mySet = new Set(); mySet.add(1); mySet.add('some text'); mySet.add('foo'); mySet.has(1); // true mySet.delete('foo'); mySet.size; // 2 for (let item of mySet) console.log(item); // 1 // "some text"
Bạn có thể tạo một {{jsxref("Array")}} từ một Set bằng cách sử dụng {{jsxref("Array.from")}} hoặc spread operator. Ngoài ra, hàm khởi tạo Set
cho phép chuyển đổi một Array
theo một hướng khác.
Note: Hãy nhớ rằng các Set
object lưu trữ các giá trị duy nhất—vì thế bất kỳ phần tử nào trùng lặp trong Array sẽ bị loại bỏ khi chuyển đổi!
Array.from(mySet); [...mySet2]; mySet2 = new Set([1, 2, 3, 4]);
Thông thường, một tập hợp các phần tử được lưu trữ trong mảng trong JavaScript trong nhiều tính huống. Tuy nhiên, Set
object có một vài điểm lợi thế sau:
arr.splice(arr.indexOf(val), 1)
) rất chậm.Set
object cho phép bạn xóa bỏ các phần tử theo giá trị của chúng. Trong khi đó một mảng, bạn sẽ phải dùng phương thức splice
dựa theo index của phần tử.indexOf
trong một mảng.Set
object lưu trữ các giá trị duy nhất. Bạn không cần phải thao tác thủ công để theo dõi các giá trị bị trùng lặp.Các {{jsxref("WeakSet")}} object là bộ sưu tập các đối tượng. Một đối tượng trong WeakSet
chỉ xuất hiện một lần. Nó là duy nhất trong bộ sưu tập WeakSet
, và các đối tượng đó không thể đếm được.
Những điểm khác biệt chính so với {{jsxref("Set")}} object:
Sets
, WeakSets
là bộ sưu tập các đối tượng và không phải bất kỳ giá trị của bất kỳ kiểu nào. WeakSet
là yếu ớt (weak): Tham chiếu tới đối tượng trong bộ sưu tập được tổ chức yếu ớt (weakly). Nếu không có tham chiếu nào khác tới đối tượng được lưu trữ trong WeakSet
, chúng có thể bị thu thập bởi garbage collected. Điều này có nghĩa là không có danh sách các đối tượng đang được lưu trữ trong bộ sưu tập. WeakSets
không thể đếm được.Các trường hợp sử dụng các WeakSet
object bị hạn chế. Chúng sẽ không rò rỉ bộ nhớ, vì thế nó có thể an toàn khi sử dụng các phần tử DOM làm khóa và đánh dấu chúng cho mục đích theo dõi.
So sánh bằng nhau của các key của các Map
object và value của các Set
object dựa trên "same-value-zero algorithm":
===
.-0
và+0
được coi là bằng nhau.===
).{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}