WeakSet
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.
* Some parts of this feature may have varying levels of support.
WeakSet là một tập hợp các giá trị có thể garbage collected, bao gồm các đối tượng và symbol không được đăng ký. Một giá trị trong WeakSet chỉ được xuất hiện một lần. Nó là duy nhất trong tập hợp của WeakSet.
Mô tả
Các giá trị của WeakSet phải là garbage-collectable. Hầu hết các kiểu dữ liệu nguyên thủy có thể được tạo tùy ý và không có vòng đời, vì vậy chúng không thể được lưu trữ. Đối tượng và symbol không được đăng ký có thể được lưu trữ vì chúng là garbage-collectable.
Các điểm khác biệt chính so với đối tượng Set là:
-
WeakSetlà tập hợp chỉ gồm đối tượng và symbol. Chúng không thể chứa các giá trị tùy ý của bất kỳ kiểu nào, nhưSetcó thể. -
WeakSetlà weak (yếu), nghĩa là các tham chiếu đến các đối tượng trongWeakSetđược giữ yếu. Nếu không có tham chiếu nào khác đến một giá trị được lưu trongWeakSet, những giá trị đó có thể bị garbage collected.Note: Điều này cũng có nghĩa là không có danh sách các giá trị hiện tại được lưu trong tập hợp.
WeakSetkhông thể liệt kê.
So sánh key
Giống như Set thông thường, so sánh giá trị dựa trên thuật toán SameValueZero, giống với toán tử === vì WeakSet chỉ có thể giữ các giá trị đối tượng và symbol. Điều này có nghĩa là đối với các giá trị đối tượng, sự bình đẳng dựa trên đồng nhất đối tượng. Chúng được so sánh theo tham chiếu, không phải theo giá trị.
Constructor
WeakSet()-
Tạo một đối tượng
WeakSetmới.
Thuộc tính thể hiện
Các thuộc tính này được định nghĩa trên WeakSet.prototype và chia sẻ bởi tất cả các thể hiện WeakSet.
WeakSet.prototype.constructor-
Hàm constructor đã tạo ra đối tượng thể hiện. Đối với các thể hiện
WeakSet, giá trị ban đầu là constructorWeakSet. WeakSet.prototype[Symbol.toStringTag]-
Giá trị ban đầu của thuộc tính
[Symbol.toStringTag]là chuỗi"WeakSet". Thuộc tính này được sử dụng trongObject.prototype.toString().
Phương thức thể hiện
WeakSet.prototype.add()-
Chèn giá trị được chỉ định vào set này, nếu nó chưa có.
WeakSet.prototype.delete()-
Xóa giá trị được chỉ định khỏi set này, nếu nó có trong set.
WeakSet.prototype.has()-
Trả về boolean cho biết giá trị được chỉ định có tồn tại trong
WeakSetnày hay không.
Ví dụ
>Sử dụng đối tượng WeakSet
const ws = new WeakSet();
const foo = {};
const bar = {};
ws.add(foo);
ws.add(bar);
ws.has(foo); // true
ws.has(bar); // true
ws.delete(foo); // removes foo from the set
ws.has(foo); // false, foo has been removed
ws.has(bar); // true, bar is retained
Lưu ý rằng foo !== bar. Mặc dù chúng là các đối tượng tương tự, chúng không phải cùng một đối tượng. Và vì vậy cả hai đều được thêm vào set.
Phát hiện tham chiếu vòng
Các hàm gọi đệ quy chính mình cần một cách để bảo vệ chống lại các cấu trúc dữ liệu vòng bằng cách theo dõi những đối tượng nào đã được xử lý.
WeakSet là lý tưởng cho mục đích này:
// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = new WeakSet()) {
// Avoid infinite recursion
if (_refs.has(subject)) {
return;
}
fn(subject);
if (typeof subject === "object" && subject) {
_refs.add(subject);
for (const key in subject) {
execRecursively(fn, subject[key], _refs);
}
_refs.delete(subject);
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar",
},
};
foo.bar.baz = foo; // Circular reference!
execRecursively((obj) => console.log(obj), foo);
Ở đây, một WeakSet được tạo trong lần chạy đầu tiên, và được truyền cùng với mỗi lần gọi hàm tiếp theo (sử dụng tham số nội bộ _refs).
Số lượng đối tượng hoặc thứ tự duyệt của chúng không quan trọng, vì vậy WeakSet phù hợp hơn (và hiệu quả hơn) so với Set để theo dõi các tham chiếu đối tượng, đặc biệt nếu có một số lượng rất lớn các đối tượng liên quan.
Đặc tả
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-weakset-objects> |