6

Như đã đề cập  trước đây , chúng tôi có một tiêu chuẩn JavaScript mới thường được gọi là ECMAScript 6 (ES6). Gần đây tôi đã dành khá nhiều thời gian để đọc xung quanh các tính năng mới được nêu trong tiêu chuẩn sắp ra mắt hoặc gần đây đã được triển khai trong các trình duyệt của chúng tôi. Một trong những bổ sung yêu thích của tôi là loại Set mới. Một bộ có phần giống như một mảng. Đó là nơi lưu trữ các giá trị: số, chuỗi, đối tượng, mảng thực tế, Booleans, các bộ khác, v.v ... Sự khác biệt đáng chú ý nhất là nó sẽ chỉ lưu trữ cùng một phần tử một lần.

Tạo và thêm các thành phần vào một tập hợp

Thật dễ dàng để thiết lập một bộ mới, trống:

var A = new Set(); //A is a set with nothing in it

Sau đó, chúng ta có thể thêm các phần tử vào tập hợp bằng phương thức add chainable:

A.add(1).add(2).add("1").add([1, 2, 3, 4, 5]).add({}); //The set now contains 5 elements of various types

Lưu ý rằng 1 và "1" là khác nhau, không có sự ép buộc kiểu nào, vì vậy cả hai có thể được thêm vào tập hợp. Mặt khác, nếu chúng ta cố gắng thêm số 1 một lần nữa, thì không có gì thay đổi:

A.add(1); //The set still contains 5 elements

Tuy nhiên, chúng ta có thể thêm một đối tượng trống khác vào mảng.

A.add({}); //The set contains 6 elements, 2 of them are empty objects

Tại sao điều này làm việc? Bởi vì hai đối tượng chỉ bằng nhau  nếu chúng tham chiếu đến cùng một không gian trong bộ nhớ . Hai đối tượng có thể chứa các thuộc tính và phương thức giống nhau nhưng chúng không được coi là bằng nhau ở đây. Điều tương tự cũng đúng với mảng:

A.add([1, 2, 3, 4, 5]); //The set contains 7 elements, including two arrays

Ngược lại, phần sau chỉ thêm một mảng vào tập hợp, không phải hai hoặc ba vì x và y tham chiếu đến cùng một đối tượng trong bộ nhớ:

var x = ['a', 'b', 'c']; var y = x; //y is an alias of x A.add(x).add(x).add(y); //Only the first call to add adds anything to the set

Bạn cũng có thể thêm các phần tử vào một tập hợp bằng cách chuyển vào bất kỳ lần lặp nào   dưới dạng đối số cho lệnh gọi xây dựng ban đầu. Tùy chọn đơn giản nhất là một mảng:

var B = new Set([7, 8, 9]); //B is a set containing 3 elements

Một cách khó hiểu, các chuỗi có thể lặp lại (nhưng, số thì không). Vì vậy, điều này dẫn đến một TypeError:

B = new Set(123); //Nope, can't do this

Nhưng, sau đây tạo ra một bộ với ba yếu tố!

B = new Set('123'); //B is a set containing three elements, the strings '1', '2' and '3'

Để thêm một chuỗi vào một bộ mới, đặt nó trong một mảng:

B = new Set(['123']); //B is a set containing the single element (string) '123'

Không có gì ngăn bạn tạo các bộ bằng cách sử dụng phương thức add:

B.add(new Set([1, 2, 3])) //B now contains 2 elements, the string '123' and the set of numbers 1, 2 and 3
B.add(new Set([7, 8, 9])) //B now contains 3 elements, including 2 sets

Mặt khác, sau đây chỉ tạo một tập hợp chứa ba số nguyên dương đầu tiên:

var C = new Set(new Set([1, 2, 3])); //Same as var C = new Set([1,2,3])

Bạn cũng có thể sao chép (chứ không phải bí danh) một bộ khác bằng cách sử dụng Bộ mới:

var D = new Set(A); //A and D are completely different sets, they just (currently) have the same members

Kiểm tra tư cách thành viên

Kiểm tra thành viên thiết lập cũng thực sự dễ dàng bằng cách sử dụng phương thức have.

A.has(1); //true A.has(2); //true A.has('1'); //true A.has(75); //false

Tất nhiên, bạn  không thể  chỉ kiểm tra một đối tượng trống hoặc mảng [1, 2, 3, 4, 5] với cùng lý do là bạn  có thể  thêm nhiều hơn một đối tượng hoặc mảng đó.

A.has({}); //false A.has([1, 2, 3, 4, 5]); //false

Tuy nhiên, bạn có thể kiểm tra các đối tượng hoặc mảng cụ thể (hoặc ngày hoặc không phải là nguyên thủy khác) mà bạn có tài liệu tham khảo.

A.has(x); //true A.has(y); //true: y is an alias for x (see above)

Xóa các thành phần khỏi tập hợp

Phương thức xóa sẽ loại bỏ các thành viên khỏi một tập hợp.

A.delete(1); //Removes 1 from the set, returns true A.has(1); //false A.delete(x); //true A.has(y); //false: y is an alias for the array x which is no longer a member of A

Như đã lưu ý trước đó, phương thức add có thể tạo chuỗi bởi vì nó trả về cái này. Ngược lại, nếu bạn sử dụng pop hoặc shift trên một mảng thông thường, chúng sẽ trả về phần tử được trích xuất. Phương thức xóa của Set không thực hiện những điều này, nó chỉ trả về Boolean để cho biết phần tử có bị xóa hay không. Do đó, bạn không thể xóa các cuộc gọi. Và tất nhiên, bạn không thể xóa một đối tượng hoặc mảng mà bạn không có tham chiếu đến:

A.delete({}); //false A.delete([1, 2, 3, 4, 5]); //false You can remove all elements from a set in one step using the clear method (which returns undefined regardless of whether anything was cleared or not):B.clear(); //B is now an empty set.

Kiểm tra kích thước của một bộ

Giống như một mảng, bạn có thể kiểm tra số lượng phần tử có trong Tập hợp. Không giống như một mảng, thuộc tính có liên quan được gọi là kích thước, không phải chiều dài.

A.size; //6: The number 2, the string '1', 2 arrays containing the numbers 1 to 5 and 2 empty objects B.size; //0

Vòng qua một bộ

Một tập hợp không cho phép bất kỳ hình thức truy cập ngẫu nhiên. Chẳng hạn, bạn không thể truy cập phần tử đầu tiên hoặc bất kỳ phần tử nào khác của tập hợp bằng cách sử dụng ký hiệu dấu ngoặc vuông như bạn có thể với một mảng. (Đã nói rằng, nếu bạn thử kết quả không xác định, không phải là lỗi.) Điều này cũng có nghĩa là bạn không thể sử dụng vòng lặp lỗi thời. vòng lặp for-in cũng không hoạt động. Tuy nhiên, có một vài lựa chọn để có được các yếu tố. Bạn có thể sử dụng  vòng lặp for -of JavaScript mới  để lặp trên bất kỳ đối tượng lặp lại nào và bao gồm các bộ. Sau đây chỉ đơn giản là ghi lại tất cả các yếu tố vào bàn điều khiển theo thứ tự chúng đã được thêm vào tập hợp:

for(var element in A) { console.log(element); //Prints out representations of the 6 elements }

Và, giống như mảng, các tập hợp có một phương thức forEach. Điều này không giống như ví dụ trên:

A.forEach(function(el){console.log(el);}); //Does the same as the for-of loop above

Công dụng và hạn chế

Tôi thích các bộ JavaScript vì chúng có vẻ tương đối dễ sử dụng. Họ cung cấp một hệ thống đơn giản để giữ và truy cập bộ sưu tập dữ liệu khi bạn không muốn lo lắng về các bản sao và các vấn đề họ có thể gây ra. Không có gì đáng ngạc nhiên, chúng cũng hơi giống với  khái niệm toán học  của một tập hợp. Do đó, có lẽ hơi ngạc nhiên khi đặc tả ES6 không bao gồm các phương thức để thực hiện các hoạt động tập hợp toán học phổ biến như  liên kếtgiao nhau và  sự khác biệt đối xứng . Hiện tại, bạn phải tự thực hiện những điều này (một số gợi ý có thể tìm thấy  ở đây). Hơn nữa, không có cách biểu diễn trực tiếp, giả sử, tập hợp tất cả các số tự nhiên hoặc tập hợp tất cả các số thực trong một tập hợp JavaScript (vì cả hai đều là tập hợp vô hạn) như bạn có thể muốn trong toán học.

Hỗ trợ trình duyệt

Hỗ trợ cho các bộ  đã tốt  trong trình duyệt máy tính để bàn. Các trình duyệt di động  vẫn đang bắt kịp .

Đọc thêm

Tôi tìm thấy cuốn sách trực tuyến  Khám phá ES6  của Tiến sĩ Axel Rauschmayer một tài liệu tham khảo tuyệt vời cho tất cả mọi thứ ES6. Chương 19  bao gồm Bộ và các "bộ sưu tập" WeakSets, Bản đồ và WeakMaps có liên quan. Bài đăng trên blog này  trên Bộ sưu tập của Jason Orendorff cho Mozilla cũng rất đáng để đọc.

|