Immutable object trong Javascript
Bài đăng này đã không được cập nhật trong 6 năm
Giới thiệu
Thông thường, object
trong JavaScript
là mutable
– nghĩa là trạng thái của object
có thể thay đổi được. Tuy nhiên, có nhiều trường hợp bạn mong muốn object
đó là immutable
– trạng thái không thể thay đổi được. Bài viết này sẽ giới thiệu với bạn một vài cách tạo immutable
object trong JavaScript
.
Sử dụng Object.defineProperty
Phương thức Object.defineProperty() định nghĩa một thuộc tính mới trên object hoặc sửa đổi thuộc tính có sẵn trên object.
Cú pháp:
/**
* @param obj: Đối tượng để xác định thuộc tính
* @param prop: Tên của thuộc tính được xác định hoặc sửa đổi.
* @param descriptor: Bộ mô tả cho thuộc tính đang được xác định hoặc sửa đổi.
*
* @return Đối tượng được truyền cho hàm.
*/
Object.defineProperty(obj, prop, descriptor)
Note: Bạn gọi phương thức này trực tiếp trên constructor
của Object
(viết hoa nhé) chứ không phải trên một instance
của Object.
Để tạo một immutable
object sử dụng Object.defineProperty
, bạn chỉ cần định nghĩa property với writable
là false
.
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
object1.property1 = 77;
// throws an error in strict mode
console.log(object1.property1);
// expected output: 42
Bạn có thể thấy gía trị của object1.property1
không thay đổi so với giá trị ban đầu mặc dù bạn đã gán lại giá trị cho nó. Ngoài ra, gía trị mặc định của writable
là false nên bạn có thể bỏ qua thuộc tính này.
const object1 = {};
Object.defineProperty(object1, 'property1', { value: 42 });
object1.property1 = 77;
console.log(object1.property1); // output: 42
Vậy mình muốn biến immutable
object thành mutable
object thì sao?
Do giá trị mặc định của configurable
(description) nên bạn không thể gán lại giá trị cho writable
sau lần define
đầu tiên (nếu chưa set giá trị cho configurable
thành true)
let obj = {};
Object.defineProperty(obj, 'a', { value: 1, writable: false });
Object.defineProperty(obj, 'a', { writable: true });
// => TypeError: Cannot redefine property: a
// Update configurable
let obj = {};
Object.defineProperty(obj, 'a', { value: 1, writable: false, configurable: true});
Object.defineProperty(obj, 'a', {writable: true });
obj.a = 2;
console.log(obj.a); // => 2
Sử dụng Object.freeze
Phương thức Object.freeze() làm cho object không thể thay đổi, bao gồm: không thể thêm thuộc tính mới vào object, thuộc tính đã có thì không thể bị xoá bỏ,…
Cú pháp:
/**
* @param obj: đối tượng mà bạn muốn freeze
*
* @return đối tượng được truyền cho hàm.
*/
Object.freeze(obj)
Ví dụ:
const object1 = {
property1: 42
};
const object2 = Object.freeze(object1);
object2.property1 = 33;
// Throws an error in strict mode
console.log(object2.property1);
// expected output: 42
Không như Object.defineProperty
, bạn không thể unfreeze
object trên sau khi nó được freeze
Sử dụng Immutable.js
Immutable.js được xây dựng và phát triển bởi facebook
, nó cung cấp cho người dùng rất nhiều cấu trúc dữ liệu ổn định, trong đó có thể kể đến: List
, Stack
, Map
, OrderedMap
, Set
, OrderedSet
, Record
.
Cài đặt:
Immutable.js
không phụ thuộc vào bất kì một package
nào nên nó có thể include trực tiếp trong html
hoặc cài đặt thông qua npm/yarn
.
Sử dụng:
const { Map } = require('immutable')
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set('b', 50)
map1.get('b') + " vs. " + map2.get('b') // 2 vs. 50
Hoặc nếu bạn sử dụng tag <script>
:
<script src="immutable.min.js"></script>
<script>
var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50
</script>
<!-- Hoặc -->
<script>
require(['./immutable.min.js'], function (Immutable) {
var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50
});
</script>
Để hiểu rõ hơn về Immutable.js
, bạn có thể đọc thêm ở đây
Tổng kết
Ở trên là 3 cách để tạo immutable
object trong javascript
. Mỗi cách đều có ưu điểm / nhược điểm riêng. Tuỳ theo từng yêu cầu cụ thể mà bạn có thể lựa chọn cách làm hợp lý.
All rights reserved