Lý thuyết
Tính bất biến là khả năng giá trị/dữ liệu của biến không bị thay đổi sau khi đã được khai báo [1].
Hiểu đơn giản là khi anh em gắn giá trị cho một biến đã được khai báo và anh em không muốn giá trị của biến đó bị thay đổi.
Vậy có cách nào giúp ta đảm bảo được tính bất biến trong JS. Trước khi nghiên cứu sâu hơn, mình cần anh em nắm được 2 khái niệm về Value type và Reference type.
1. Value type vs Reference type
Value type |
Reference type |
---|---|
Các biến dạng Value type lưu trữ giá trị | Các biến dạng Reference type lưu trữ địa chỉ |
Gồm string, int, bool, null, undefined | Gồm Object, Array |
Ta tạo một biến x dưới dạng Value type và tạo một biến y gắn bằng x. Khi ta thay đổi giá trị của 1 trong 2 biến, thì giá trị của biến còn lại sẽ không đổi.
var x = 1;
var y = x;
y = 2;
console.log(`x: ${x}, y: ${y}`); // x: 1, y: 2
Ta tạo một biến mới dưới dạng Reference type và tạo một biến y gắn bằng x. Khi ta thay đổi giá trị thuộc tính của 1 trong 2 biến, thì giá trị của biến còn lại sẽ thay đổi vì bản chất 2 biến đang trỏ tới cùng một địa chỉ.
var x = {number: 1};
var y = x;
y.number = 2;
console.log(`x: ${JSON.stringify(x)}, y: ${JSON.stringify(y)}`); // x: {"number":2}, y: {"number":2}
Đang tiện phần trình bày về Value type và Reference type nên mình nói hơi lạc đề một chút 😜
Gói gọn lại trong phần 1 này, anh em chỉ cần nắm được Value type gồm string, int, bool, null, undefined; Reference type gồm Object, Array để xử lý tính bất biến cho phù hợp.
OK, anh em mình cùng nhau đi vào chủ đề chính của bài hôm nay nào.
2. Const
Dùng const giúp đảm bảo tính bất biến cho các biến dạng Value type.
const name = "pdthien"
name = "123"
Giá trị của biến name sẽ được đảm bảo. Nếu cố tình thay đổi, chúng ta sẽ gặp lỗi
Đối với object (Reference type), chúng ta cũng sẽ gặp lỗi tương tự, nếu cố tình thay đổi giá trị của biến.
const person = { name: "pdthien"
}
person = { name: "123"
}
Tuy nhiên khi chúng ta thay đổi giá trị của thuộc tính thì lúc này tính bất biến không còn được duy trì.
const person = { name: "pdthien"
}
person.name = 123
console.log(person) // {name: 123}
Trong ví dụ trên, giá trị của thuộc tính name trong biến person đã bị thay đổi, không còn đảm bảo được tính bất biến. Đối với Array chúng ta cũng sẽ gặp tình trạng tương tự:
const number = [1, 2, 3];
number[1] = 100;
console.log(number); // [1, 100, 3]
Vậy có cách nào giúp cho các biến dạng Reference type đảm bảo được tính bất biến không. Rất may mắn, chúng ta có 1 cách giúp giải quyết điều này, đó là Object.freeze.
3. Object.freeze
var person = Object.freeze({ name: "pdthien"
})
person.name = 123
console.log(person) // {name: "pdthien"}
Lúc này, giá trị của biến person không đổi, tính bất biến đã được đảm bảo, tượng tự đối với Array cũng vậy.
Một số đặc trưng của Object.freeze chúng ta cần nắm được:
- Dùng cho Reference Type.
- Ngăn chặn:
- Thêm thuộc tính mới.
- Sửa đổi giá trị thuộc tính đang tồn tại.
- Xóa các thuộc tính đang tồn tại.
Tuy nhiên, một tình huống đánh bay tính bất biến mặc dù chúng ta đã áp dụng Object.freeze
var person = Object.freeze({ name: "pdthien"
})
person = { name: 123
}
console.log(person) // {name: 123}
Do biến person được khai báo bằng var, nên khi ta gắn person bằng một giá trị bất kỳ, tính bất biến sẽ không còn được đảm bảo.
Vậy lời khuyên tốt nhất được đưa ra để đảm bảo được tính bất biến cho Reference type là kết hợp sử dụng const và Object.freeze.
const person = Object.freeze({ name: "pdthien"
})
Kết
- Dùng const cho biến dạng Value type.
- Dùng const kết hợp Object.freeze cho biến dạng Reference type.
Rất cảm ơn anh em đã đọc tới đây ạ 😘