0
0
Lập trình
Admin Team
Admin Teamtechmely

So sánh Shallow Copy và Deep Copy trong JavaScript: Hướng dẫn chi tiết và Best Practices

Đăng vào 1 tháng trước

• 4 phút đọc

Chủ đề:

Javascript

So sánh Shallow Copy và Deep Copy trong JavaScript

Sao chép cấu trúc dữ liệu là một trong những thao tác quan trọng nhất khi làm việc với đối tượng và mảng trong JavaScript. Tuy nhiên, các nhà phát triển thường gặp khó khăn trong việc lựa chọn giữa Shallow Copy (sao chép nông) và Deep Copy (sao chép sâu). Việc hiểu rõ sự khác biệt giữa hai phương thức này có thể giúp bạn tránh được những tác dụng phụ không mong muốn trong mã của mình.

Shallow Copy là gì?

Shallow Copy chỉ tạo ra một đối tượng mới với các bản sao của các thuộc tính cấp cao nhất của đối tượng gốc. Với các thuộc tính là kiểu nguyên thủy, bạn sẽ nhận được giá trị sao chép. Ngược lại, nếu thuộc tính là đối tượng (như mảng hay đối tượng lồng nhau), chỉ có tham chiếu được sao chép, không phải dữ liệu thực tế.

Ví dụ:

javascript Copy
const original = {
  name: "Alice",
  details: {
    age: 25,
    city: "Wonderland"
  }
};

// Shallow copy
const shallowCopy = { ...original };

// Sửa đổi đối tượng lồng nhau trong bản sao nông
shallowCopy.details.city = "Looking Glass";

// Đối tượng gốc cũng bị ảnh hưởng
console.log(original.details.city); // Kết quả: "Looking Glass"

Cách tạo bản Shallow Copy

1. Sử dụng toán tử spread (...):

javascript Copy
const shallowCopy = { ...originalObject };

2. Sử dụng Object.assign():

javascript Copy
const shallowCopy = Object.assign({}, originalObject);

Các phương pháp này nhanh chóng và dễ thực hiện, nhưng không hiệu quả với các cấu trúc dữ liệu lồng nhau phức tạp.

Deep Copy là gì?

Deep Copy sẽ sao chép mọi thuộc tính và thuộc tính con của đối tượng gốc. Điều này đảm bảo rằng bản sao hoàn toàn độc lập với đối tượng gốc, và các thay đổi trong bản sao không ảnh hưởng đến đối tượng gốc.

Deep Copy rất quan trọng khi bạn làm việc với các cấu trúc dữ liệu phức tạp như đối tượng hoặc mảng lồng nhau. Đặc biệt trong những trường hợp mà tính toàn vẹn dữ liệu là tối quan trọng.

Ví dụ:

javascript Copy
const original = {
  name: "Alice",
  details: {
    age: 25,
    city: "Wonderland"
  }
};

// Deep copy bằng các phương thức JSON
const deepCopy = JSON.parse(JSON.stringify(original));

// Sửa đổi đối tượng lồng nhau trong bản sao sâu
deepCopy.details.city = "Looking Glass";

// Đối tượng gốc không thay đổi
console.log(original.details.city); // Kết quả: "Wonderland"

Cách tạo bản Deep Copy

1. Sử dụng JSON.stringify() và JSON.parse():

Chuyển đổi đối tượng thành chuỗi JSON và phân tích cú pháp trở lại thành một đối tượng mới. Tuy nhiên, phương pháp này có một số hạn chế: không thể xử lý các tham chiếu vòng và sẽ bỏ qua các thuộc tính như hàm, undefined, hoặc Symbol.

javascript Copy
const deepCopy = JSON.parse(JSON.stringify(originalObject));

2. Sử dụng thư viện:

Các thư viện như Lodash cung cấp các phương thức sao chép sâu mạnh mẽ.

javascript Copy
const _ = require('lodash');
const deepCopy = _.cloneDeep(originalObject);

3. Viết hàm đệ quy tùy chỉnh:

Bạn có thể viết một hàm đệ quy để kiểm soát hoàn toàn quy trình sao chép các đối tượng lồng nhau.

So sánh giữa Shallow Copy và Deep Copy

Khi nào nên sử dụng Shallow Copy?

  • Đối tượng phẳng: Khi bạn chỉ xử lý các đối tượng đơn giản không chứa thuộc tính lồng nhau.
  • Hiệu suất: Khi tốc độ là ưu tiên và bạn không cần xử lý dữ liệu lồng nhau sâu.
  • Thay đổi tạm thời: Khi bạn chỉ cần sửa đổi các thuộc tính cấp cao nhất.

Ví dụ:

javascript Copy
const userSettings = { theme: "dark", layout: "grid" };
const updatedSettings = { ...userSettings, layout: "list" };

Khi nào nên sử dụng Deep Copy?

  • Cấu trúc phức tạp: Khi đối tượng có nhiều cấp độ lồng nhau.
  • Tránh tác dụng phụ: Khi bạn muốn đảm bảo rằng các thay đổi trong bản sao không ảnh hưởng đến bản gốc.
  • Quản lý trạng thái: Trong các framework như React hoặc Redux, nơi tính bất biến là rất quan trọng.

Ví dụ:

javascript Copy
const gameState = {
  level: 5,
  inventory: {
    weapons: ["sword", "shield"],
    potions: 3
  }
};

// Deep copy đảm bảo không có tác dụng phụ
const savedState = JSON.parse(JSON.stringify(gameState));

Những sai lầm và cạm bẫy thường gặp

  • Cho rằng Shallow Copy luôn đủ: Nhiều nhà phát triển lạm dụng các phương pháp shallow copy cho các đối tượng lồng nhau dẫn đến những thay đổi không như mong đợi trong dữ liệu gốc.
  • Lạm dụng phương thức JSON: Mặc dù JSON.stringify/JSON.parse đơn giản nhưng không hoạt động cho tất cả các đối tượng.
  • Bỏ qua hiệu suất: Các phương pháp deep copy có thể chậm hơn, đặc biệt với các đối tượng lớn, vì vậy cần cẩn thận khi sử dụng.

Kết luận

Hiểu rõ sự khác biệt giữa Shallow Copy và Deep Copy là chìa khóa để viết mã JavaScript chính xác và hiệu quả. Shallow Copy thích hợp cho các cấu trúc dữ liệu phẳng, trong khi Deep Copy là lựa chọn không thể thiếu cho các đối tượng phức tạp. Hãy lựa chọn phương pháp phù hợp tùy theo cấu trúc dữ liệu và nhu cầu của ứng dụng, đồng thời nhận thức về các cạm bẫy tiềm ẩn từ từng phương pháp.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào