Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

So sánh 2 object trong JavaScript

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ápDeepKey orderFunction/UndefinedCircularDependency
===NoN/AReferenceN/AKhông
JSON.stringifyCó*Phụ thuộcMấtLỗiKhông
_.isEqualCóBỏ quaReferenceOKLodash
Custom deepEqualCóBỏ quaReferenceStack overflowKhông
assert.deepStrictEqualCóBỏ quaStrictOKNode.js

Kết luận

  • Object đơn giản, key order cố định, không function/circular → JSON.stringify OK.
  • 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).