Object so sánh bằng === hoặc == chỉ kiểm tra reference equality (cùng vùng nhớ) — không so sánh nội dung.
Vấn đề
const a = { x: 1 };
const b = { x: 1 };
a === b; // false — khác reference
a == b; // false
Cách 1: JSON.stringify() — Đơn giản nhưng có hạn chế
JSON.stringify(obj1) === JSON.stringify(obj2);
Nhược điểm
- Phụ thuộc thứ tự key:
{a:1,b:2}vs{b:2,a:1}→ false. - Mất function, undefined, Symbol.
- Circular reference → Error.
- Date → ISO string (so sánh được), RegExp →
{}(sai).
Ví dụ fail do thứ tự key
const obj1 = { name: 'Rahim', city: 'Hyderabad', country: 'India' };
const obj2 = { name: 'Rahim', country: 'India', city: 'Hyderabad' };
JSON.stringify(obj1) === JSON.stringify(obj2); // false — sai!
Cách 2: Lodash _.isEqual() — Chuẩn, mạnh mẽ (Khuyên dùng)
_.isEqual(obj1, obj2); // true — bỏ qua thứ tự key, deep compare
Cách 3: Custom Deep Equal (Không dependency)
function deepEqual(a, b) {
if (a === b) return true;
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;
const keysA = Object.keys(a), keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
}
return true;
}
// Test
deepEqual({a:1, b:{c:2}}, {b:{c:2}, a:1}); // true
Cách 4: Node.js assert.deepStrictEqual() (Test)
const assert = require('assert');
assert.deepStrictEqual(obj1, obj2); // Throw nếu không equal
Bảng so sánh
| Phương pháp | Deep | Key order | Function/Undefined | Circular | Dependency |
|---|---|---|---|---|---|
=== | No | N/A | Reference | N/A | Không |
JSON.stringify | Có* | Phụ thuộc | Mất | Lỗi | Không |
_.isEqual | Có | Bỏ qua | Reference | OK | Lodash |
| Custom deepEqual | Có | Bỏ qua | Reference | Stack overflow | Không |
assert.deepStrictEqual | Có | Bỏ qua | Strict | OK | Node.js |
Kết luận
- Object đơn giản, key order cố định, không function/circular →
JSON.stringifyOK. - Production, object phức tạp, cần đúng chuẩn → Lodash _.isEqual().
- Không muốn dependency → tự viết deepEqual (nhưng xử lý kém edge case).