Hướng dẫn thử thách
1 / 2
What Are Sets in JavaScript, and How Does It Differ from WeakSets?
In JavaScript, `Set` is a built-in object for managing data collections. It lets you store unique values of any type, whether primitive or object references. `Set` ensures that each value in it appears only once, making it useful for eliminating duplicates from an array or handling collections of distinct values.
As for `WeakSet`, it’s a special type of `Set` with fewer features that allows you to store weakly held object references and symbols. Unlike `Set`, `WeakSet` does not support primitives like numbers or strings.
Unlike a regular `Set`, a `WeakSet` only stores objects, and the references to those objects are "weak" meaning WeakSets do not prevent the stored objects from being garbage-collected if there are no other references to them. In simpler terms, if the object is not being used anywhere else in your code, it is removed automatically to free up memory.
To create a `Set`, you use the `Set` constructor and assign it to a variable:
```js
const myFirstSet = new Set();
```
You can also initialize the `Set` with values:
```js
const treeSet = new Set(["Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"]);
```
If you log the `Set` to the console, this is what the output looks like:
```js
/*
Set(4) {"Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"}
[[Entries]]
0: "Baobab"
value: "Baobab"
1: "Jackalberry"
value: "Jackalberry"
2: "Mopane Tree"
value: "Mopane Tree"
3: "Breadfruit"
value: "Breadfruit"
size: 4
[[Prototype]]: Set
*/
```
If you didn't initialize the `Set` with values, you can use the `add()` method to add an item to the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
```
The result and appearance of the result in the console remains the same.
Don't forget that duplicate items will be ignored in the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.add("Baobab"); //duplicate item will be ignored
console.log(treeSet);
// Set(4) {"Baobab", "Jackalberry", "Mopane Tree", "Breadfruit"}
```
The other methods you can use to manipulate a `Set` are:
- `delete()`
- `clear()`
- `has()`
- `entries()`
- `forEach()`
- `keys()`
- `values()`
Let's look at how these methods work one by one. `delete()` removes a specified item from the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet); // Set(3) {"Baobab", "Jackalberry", "Mopane Tree"}
```
`has()` checks if a specified value exists in the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.has("Breadfruit")); // false
```
`entries()` returns a `Set` iterator containing an array of the values in a `[value, value]` format:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.entries());
// SetIterator {"Baobab" => "Baobab", "Jackalberry" => "Jackalberry", "Mopane Tree" => "Mopane Tree"}
```
`keys()` and `values()` show the values in the `Set`. `keys()` is just an alias for the `values()` method:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log("Keys: ", treeSet.keys());
console.log("Values: ", treeSet.values());
// Keys: SetIterator {"Baobab", "Jackalberry", "Mopane Tree"}
// Values: SetIterator {"Baobab", "Jackalberry", "Mopane Tree"}
```
`forEach()` lets you iterate through the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
treeSet.forEach((tree) => console.log(tree));
/*
Baobab
Jackalberry
Mopane Tree
*/
```
`clear()` removes all the items of the array:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
treeSet.clear();
console.log(treeSet); // Set(0) {size: 0}
```
It is also worth mentioning that there's a `size` property that returns the number of items in the `Set`:
```js
const treeSet = new Set();
// Add items to the treeSet
treeSet.add("Baobab");
treeSet.add("Jackalberry");
treeSet.add("Mopane Tree");
treeSet.add("Breadfruit");
treeSet.delete("Breadfruit");
console.log(treeSet.size); // 3
```
Just like `Set`, there's also a `WeakSet` constructor you can use to create a `WeakSet`:
```javascript
const treeWeakSet = new WeakSet();
```
`WeakSet` also has the `add()`, `delete()`, and the `has()` methods:
```javascript
const treeWeakSet = new WeakSet();
const baobab = { name: "Baobab" };
const jackalberry = { name: "Jackalberry" };
const mopaneTree = { name: "Mopane Tree" };
const breadfruit = { name: "Breadfruit" };
treeWeakSet.add(baobab);
treeWeakSet.add(jackalberry);
treeWeakSet.add(mopaneTree);
treeWeakSet.add(breadfruit);
treeWeakSet.delete(jackalberry);
console.log(treeWeakSet.has(jackalberry)); // false
console.log(treeWeakSet);
```
In the output, the contents of the `WeakSet` appear like this:
```javascript
/*
WeakSet {{…}, {…}, {…}}
[[Entries]]
0: value: {name: "Mopane Tree"}
1: value: {name: "Baobab"}
2: value: {name: "Breadfruit"}
[[Prototype]]: WeakSet
*/
```
The contents are visible here because the object variables still hold strong references, keeping those objects in memory. Keep in mind that WeakSets are not iterable, so there is no way to loop over their entries or access them programmatically. What you see in the output is only a debugging aid.
Don't forget that only symbols and objects with well-defined keys and values are supported. Adding a primitive, such as numbers or strings, will result in an error:
```js
treeWeakSet.add("Alan Smith");
console.log(treeWeakSet); // Invalid value used in weak set
// at WeakSet.add (<anonymous>)
```
The key difference between a `Set` and a `WeakSet` is that a `Set` stores any value, while a `WeakSet` can only store objects.
Here are some other noticeable differences between a `Set` and a `WeakSet`:
| Feature | Set | WeakSet |
| --- | --- | --- |
| Type of Values Stored | Stores any data type | Stores only objects |
| Referencing | Strong referencing | Weak referencing |
| Iteration | Supports iteration with `forEach` and loops | Does not support iteration |
| Methods and Properties | `add()`, `delete()`, `has()`, `keys()`, `values()`, `size`, and more | `add()`, `delete()`, and `has()` only |
| Use case | General-purpose collection of unique values and removing duplicates from arrays | Efficient memory tracking of object references |
You can see the differences in the types of values that the two kinds of sets can store, their support for iterating over the stored objects and their ideal use cases. Please take a moment to read the content of this table.
Vượt qua bài kiểm tra hiện tại để mở khóa bài tiếp theo.
main.js
UTF-8 • Tab Size: 2Kiểm tra bài:⌘↵