Trong JS có ít nhất hơn 10 loại dữ liệu bao gồm kiểu cơ bản và mở rộng. Nhưng chung quy lại thì chỉ có 2 đặc tính là có thể thay đổi được (mutable) và không thể thay đổi được (immutable)

Đoạn mã sau trình bày khái niệm immutable mutable

let A = [1, 2, 3];
let B = A;
// đây là lệnh thay đổi giá trị của array
A[0] = 5; // A = B = [5, 2, 3]
// nhưng đây là lệnh thay đổi giá trị của biến
A = []; // A = [], B = [5, 2, 3]
let str = 'Hello World';
// lệnh gán sau không làm thay đổi giá trị của str
str[1] = 'a'; // str = 'Hello World'
// tương tự vậy, kết quả không phải là 200 như mong đợi
let num = 100;
num[0] = 2; // num = 100

Đa phần các primitive typeimmutable: string, null, undefined, boolean, number. Có một vài ngoại lệ như

undefined = 100; // gán giá trị cho undefined vẫn hợp lệ
// nhưng nó vẫn không thay đổi
typeof undefined; // undefined
undefined === 100; // false
// gán giá trị cho null, string hoặc boolean là ăn hành ngay
null = 100; // Uncaught ReferenceError: Invalid left-hand side in assignment

Và đặc biệt hơn

let str = '100';
let num = Number(str); // num = 100
// nhưng
let otherNum = new Number(str);
typeof otherNumber; // object
typeof num; // number
otherNumber == 100; // true
otherNumber === 100; // false
otherNumber == num; // true
otherNumber === num; // false
// cố gắng tạo một vài thuộc tính
num.isOdd = true;
num.isOdd; // undefined
otherNumber.isOdd = true;
otherNumber.isOdd; // true

Vậy khi sử dụng new với những function String, Number, Boolean chúng ta luôn nhận về object và nó có thể thay đổi được.

Hầu hết các kiểu dữ liệu object đề u có thể thay đổi được nhưng, thiệt tình là trong JS luôn có chữ nhưng cho đời rắc rối

let nullValue = null;
typeof nullValue; // object
nullValue.prop = 100; // ăn hành ngay

null là một thằng khá đặc biệt, nó có type là object nhưng lại không thể làm gì với nó được cả và chú ý là null không phải là undefined nhưng (lại nhưng)

null == null; // true
null === null; // true
null == undefined; // true, không phải nhưng sao lại bằng
null === undefined; // false

NaN không phải là một kiểu dữ liệu, nhưng nó có những đặc tính quái dị nhất

NaN == NaN; // false, oạch, sao lại không bằng nhau
NaN === NaN; // false
typeof NaN; // number
typeof NaN == typeof NaN; // true
let myNaN = NaN;
myNaN == myNaN; // false, gắt thế, so sánh chính mình cũng không được
myNaN === myNaN; // false

Kiểu dữ liệu Symbol mới được giới thiệu trong ES6 cũng thú vị không kém

let mySymbol = Symbol('Test');
Symbol('Test') == Symbol('Test'); // false
Symbol('Test') === Symbol('Test'); // false
mySymbol == Symbol('Test'); // false
mySymbol === Symbol('Test'); // false
mySymbol == mySymbol; // true
mySymbol === mySymbol; // true

Không giống như NaN, Symbol vẫn dễ chịu ở một số điểm nhất định

ArrayDatemutable, nên dùng rất dễ dàng

let array = [1, 2, 3];
array[0] = 4; // array = [4, 2, 3]
let date = new Date(2018, 1, 1); // 2018-01-01
date.setFullYear(2019); // 2019-01-01

Vậy nếu muốn sử dụng ArrayDate như immutable object thì sao ? Đơn giản chúng ta cần sao chép chúng trước khi thay đổi

let A = [1, 2, 3];
let B = A.concat(4); // A = [1, 2, 3], B = [1, 2, 3, 4]
let C = A.slice(1).concat(5); // A = [1, 2, 3], C = [2, 3, 5]
let A = new Date(2018, 1, 1);
let B = new Date(new Date(A).setFullYear(2019)); // A = 2018-01-01, B = 2019-01-01

Kết

Hiểu rõ được immutable và mutable giúp chúng ta sử dụng linh hoạt các kiểu dữ liệu trong JS cũng như phòng tránh được những lỗi không mong muốn khi

Nguồn: JS Land

Đánh giá bài viết

Thích thì like
Immutable và Mutable trong Javascript
5/5 1 votes

Bình luận

Hiển thị bình luận Facebook