- vừa được xem lúc

So sánh Object trong JavaScript​ - giống mà không giống

0 0 3

Người đăng: Nguyễn Văn Khải

Theo Viblo Asia

Việc so sánh object trong JavaScript là một yêu cầu phổ biến mà mọi developer đều gặp phải. Khác với các kiểu dữ liệu nguyên thủy có thể so sánh trực tiếp bằng toán tử ===, object yêu cầu những phương pháp tinh tế hơn để đảm bảo tính chính xác và hiệu suất tối ưu.

Tại Sao So Sánh Object Lại Phức Tạp?

JavaScript phân biệt hai loại so sánh chính: referential equality (so sánh tham chiếu) và deep equality (so sánh sâu). Toán tử === chỉ kiểm tra xem hai object có cùng tham chiếu trong bộ nhớ hay không, không phải nội dung thực tế: image.png

Object Đơn Giản

1.JSON.stringify()

Đối với object đơn giản không chứa function, undefined hoặc circular references, JSON.stringify() là lựa chọn hiệu quả nhất

const obj1 = { id: 1, name: 'Product A', price: 100 };
const obj2 = { id: 1, name: 'Product A', price: 100 }; console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true

Ưu điểm:

  • Tốc độ xử lý nhanh
  • Cú pháp đơn giản, dễ hiểu
  • Phù hợp với object có cấu trúc cố định

Nhược điểm:

  • Thứ tự thuộc tính ảnh hưởng kết quả
  • Không xử lý được undefined, function, Symbol
  • Các giá trị NaN và Infinity được chuyển thành null

2.Object Flat

Bạn có thể so sánh thủ công như sau:

function compareSimpleObjects(obj1, obj2) { const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; for (let key of keys1) { if (obj1[key] !== obj2[key]) return false; } return true;
}

Object Phức Tạp

Khi object trở nên phức tạp, lồng nhiều cấp hoặc chứa array, việc dùng stringify không còn hiệu quả. Lúc này, bạn cần đến so sánh đệ quy:

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); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (let key of keysA) { if (!keysB.includes(key) || !deepEqual(a[key], b[key])) { return false; } } return true;
}

Ưu điểm:

  • Có thể so sánh object lồng nhau, array, giá trị null.

Nhược điểm:

  • Hiệu suất kém với object lớn hoặc lồng sâu.
  • Không xử lý được circular reference, dẫn đến lặp vô hạn.

Tối ưu hóa đệ quy

Các kỹ thuật tối ưu được áp dụng:

  • Early termination: Dừng sớm khi phát hiện khác biệt
  • Circular reference handling: Sử dụng WeakMap(tương tự Map nhưng key chỉ có thể là object) để tránh vòng lặp vô hạn
  • Reference comparison: Kiểm tra tham chiếu trước khi so sánh sâu
function optimizedDeepEqual(obj1, obj2, visited = new WeakMap()) { // Early termination - so sánh tham chiếu trước if (obj1 === obj2) return true; // Kiểm tra circular reference if (visited.has(obj1)) { return visited.get(obj1) === obj2; } visited.set(obj1, obj2); // Kiểm tra kiểu dữ liệu if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) { return false; } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); // Early termination - kiểm tra số lượng thuộc tính if (keys1.length !== keys2.length) return false; // So sánh từng thuộc tính for (let key of keys1) { if (!keys2.includes(key)) return false; if (!optimizedDeepEqual(obj1[key], obj2[key], visited)) { return false; } } return true;
}

Tổng kết

Khi làm việc với object phức tạp nhiều cấp, cần chú ý:

  • Tránh JSON.stringify() với object lớn vì có thể gây stack overflow
  • Sử dụng thư viện chuyên dụng thay vì tự viết đệ quy cho production
  • Cân nhắc shallow comparison trước khi thực hiện deep comparison
  • Monitoring memory usage khi xử lý object có circular references

Bình luận

Bài viết tương tự

- vừa được xem lúc

Điểm mặt 10 project đang làm mưa làm gió trên Github trong lĩnh vực phát triển web

Nguồn: https://iainfreestone.hashnode.dev/10-trending-projects-on-github-for-web-developers-12th-march-2021. .

0 0 91

- vừa được xem lúc

Cách đơn giản để thay đổi code CSS cho việc giảm thời gian tải trang.

Technofunnel đã trình bày thêm một bài viết để giúp hướng dẫn bạn cách giảm thời gian tải trang bằng cách áp dụng một thủ thuật đơn giản trong HTML. Tác động của CSS đến thời gian tải trang.

0 0 40

- vừa được xem lúc

HTML

Giả sử bạn có một chuỗi HTML mà bạn lấy từ API hoặc bạn tự viết ra nó. Một chuỗi HTML. `. Bạn có thể dùng innerHMTL để truyền nó vào một phần tử.

0 0 14

- vừa được xem lúc

Blog#173: Introduction to Advanced JavaScript Concepts - Advanced JavaScript Part 1

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . JavaScript is an essential language for web development, and learning advanced concepts can significantly improve your programming skills.

0 0 25

- vừa được xem lúc

Blog#174: 🤔Understanding Asynchronous JavaScript: 🔄Callbacks, 🤞Promises, and 🤝Async/Await

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . 1. Introduction to Asynchronous JavaScript. What is Asynchronous JavaScript.

0 0 32

- vừa được xem lúc

Blog#175: 🧐Mastering JavaScript's Execution Context and Closures🚀

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo . 1. Understanding Execution Context. A Quick Overview.

0 0 31