Nội dung bài viết
Thật đơn giản để so sánh các kiểu dữ liệu nguyên thủy (Primitive data types) trong Javascript. Toán tử ==
trả về true
nếu các toán hạng bằng nhau, toán tử ===
trả về true
nếu các toán hạng bằng nhau và cùng kiểu.
1 == '1'; // => true 1 === '1'; // => false
Tuy nhiên đối với object, sẽ có một chút khó khăn vì chúng là dữ liệu có cấu trúc. Trong bài này mình sẽ cùng các bạn đi tìm hiểu những cách so sánh 2 object trong javascript. Bắt đầu thôi
1. So sánh bằng tham chiếu (Referential equality)
Javascript cung cấp 3 cách so sánh bằng tham chiếu 2 object:
- Toán tử bằng chính xác
===
- Toán tử bằng
==
- Hàm
Object.is()
Khi thực hiện so sánh các object bằng bất kì cách nào phía trên, kết quả sẽ là true
nếu 2 giá trị được so sánh có cùng vùng nhớ. Đây chính là so sánh bằng tham chiếu.
Cùng đi qua ví dụ về so sánh bằng tham chiếu nhé.
const hero1 = { name: 'Batman' }; const hero2 = { name: 'Batman' }; hero1 === hero1; // => true hero1 === hero2; // => false hero1 == hero1; // => true hero1 == hero2; // => false Object.is(hero1, hero1); // => true Object.is(hero1, hero2); // => false
Các bạn có thể xem hình dưới đây, add_1(object)
đại diện cho vùng nhớ mà hero1
tham chiếu đến, add_1(name)
đại diện cho vùng nhớ mà hero1.name
tham chiếu đến.

Sơ đồ vùng nhớ
hero1 === hero1
là true
bởi vì cả 2 object đều trỏ đến 1 vùng nhớ
hero1 === hero2
là false
bởi vì hero1
và hero2
trỏ đến 2 vùng nhớ khác nhau dù cho chúng có cấu trúc tương đồng và giá trị name
đều là batman
.
Phép so sánh bằng tham chiếu rất hữu ích khi bạn muốn so sánh tham chiếu của 2 giá trị, nhưng trong nhiều trường hợp thì bạn cần so sánh giá trị thực sự của 2 object chẳng hạn: các thuộc tính và giá trị bên trong nó. Vậy thì xem cách bên dưới coi thử giúp được gì không nhé.
2. So sánh thủ công (Manual comparison)
Đây là cách so sánh khá rõ ràng và dễ hiểu. Ví dụ function isHeroEqual()
dưới đây so sánh 2 object hero
function isHeroEqual(object1, object2) { return object1.name === object2.name; } const hero1 = { name: 'Batman' }; const hero2 = { name: 'Batman' }; const hero3 = { name: 'Joker' }; isHeroEqual(hero1, hero2); // => true isHeroEqual(hero1, hero3); // => false
isHeroEqual()
truy cập đến thuộc tính name
của cả 2 object và thực hiện so sánh 2 giá trị của chúng.
Nếu object có vài thuộc tính đơn giản thì chúng ta có thể viết function so sánh như isHeroEqual()
. Cách này đem lại hiệu suất tốt nhưng nếu object lớn với nhiều thuộc tính chồng lên nhau thì đây không phải là cách hữu hiệu, vì code sẽ rất dài và khó đọc.
3. So sánh nông (Shallow equality)
Trong quá trình so sánh nông, các object của bạn sẽ được lấy các thuộc tính (bằng cách dùng Object.keys()
), sau đó sẽ kiểm tra giá trị của các thuộc tính đó bằng cách so sánh tham chiếu
Đây là cách so sánh nông hoạt động
function shallowEqual(object1, object2) { const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length !== keys2.length) { return false; } for (let key of keys1) { if (object1[key] !== object2[key]) { return false; } } return true; }
Bên trong function phía trên, keys1
và keys2
là các mảng chứa danh sách tên thuộc tính của object1
và object2
.
Vòng lặp for sẽ lặp qua từng key và thực hiện phép so sánh tham chiếu bằng toán tử không bằng chính xác object1[key] !== object2[key]
.
Cùng mình xem kết quả so sánh dưới nhé
const hero1 = { name: 'Batman', realName: 'Bruce Wayne' }; const hero2 = { name: 'Batman', realName: 'Bruce Wayne' }; const hero3 = { name: 'Joker' }; shallowEqual(hero1, hero2); // => true shallowEqual(hero1, hero3); // => false
Ừm… Không có gì phải thắc mắc ở đây, nhưng hãy xem tiếp ví dụ phía dưới nữa nhé
const hero1 = { name: 'Batman', address: { city: 'Gotham' } }; const hero2 = { name: 'Batman', address: { city: 'Gotham' } }; shallowEqual(hero1, hero2); // => false

Sơ đồ vùng nhớ
Lần này thì cả hero1
và hero2
có nội dung y hệt nhau nhưng kết quả so sánh lại trả về là false
. Điều này xảy ra bởi vì giá trị hero1.address
và hero2.address
không còn là kiểu dữ liệu nguyên thủy nữa, nó đã trở thành object, vì thế javascript sẽ so sánh tham chiếu của hero1.address
và hero2.address
. Lúc này hero1.address
và hero2.address
thuộc 2 vùng nhớ khác nhau.
May mắn là cho ta vẫn còn một cách so sánh nữa, đó là so sánh sâu, nó sẽ giúp chúng ta so sánh đầy đủ nội dung bên trong của object.
4. So sánh sâu (Deep equality)
So sánh sâu thì khá tương đồng với so sánh nông, nhưng thay vì so sánh nông chỉ so sánh một cấp thì so sánh sâu sẽ so sánh nhiều cấp, nó sẽ thực hiện so sánh toàn bộ thuộc tính của object. Với phép so sánh sâu này thì bạn có thể hiểu là nếu nội dung 2 object y hệt nhau thì nó sẽ bằng nhau.
Cùng xem cách mà so sánh sâu hoạt động nhé
function deepEqual(object1, object2) { const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length !== keys2.length) { return false; } for (const key of keys1) { const val1 = object1[key]; const val2 = object2[key]; const areObjects = isObject(val1) && isObject(val2); if ( areObjects && !deepEqual(val1, val2) || !areObjects && val1 !== val2 ) { return false; } } return true; } function isObject(object) { return object != null && typeof object === 'object'; }
Như bạn thấy bên trên, ta thực hiện đệ quy để có thể lặp hết vào trong các thuộc tính của object. Cùng xem ví dụ thử nhé
const hero1 = { name: 'Batman', address: { city: 'Gotham' } }; const hero2 = { name: 'Batman', address: { city: 'Gotham' } }; deepEqual(hero1, hero2); // => true
So sánh sâu sẽ giúp ta xác định một cách chính xác 2 object có thực sự bằng nhau về mặt nội dung hay không.
Đọc thêm:
- Thay đổi một thuộc tính của object trong React sao cho chuẩn
- Bạn đã thực sự hiểu về tham trị và tham chiếu Javascript?
Để thực hiện so sánh sâu, mình khuyên sử dụng
- isDeepStrictEqual(object1, object2): Một util được build sẵn trong Node
- hoặc _.isEqual(object1, object2) của thư viện lodash
5. Tóm lại
Bài hôm nay khá đơn giản, hy vọng bài viết của mình giúp các bạn hiểu được cách so sánh các object trong javascript. Chúc các bạn cuối tuần vui vẻ 😆 , nếu có gì thắc mắc có thể comment phía bên dưới, mình sẽ giải đáp
Tham khảo: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/
mình đã đọc khá nhiều bài viết trên trang này, nhưng đây là lần đầu tiên m để lại cmt, vì nó thật sự hay :3 giúp m hiểu sâu hơn 1 vài vấn đề mà mình đã từng gặp phải. Thanks you bạn Được nhé 😀
Cảm ơn bác nhé 😂
Thanks ad ạ :3
Nice post, keep goin’. Thanks for sharing your exp, this is awesome