Copy object trong javascript

Object đơn giản

Trong Javascript có rất nhiều cách để copy một đối tượng, ví dụ 1 trong các cách là sử dụng chức năng phân rã object của Javascript:

let srcObj = {
                 data: 'someData',
                 text: 'someText',
                 number: 'someNumber'
              };
let copyObj = {...srcObj}; // phân rã object
console.log(JSON.stringify(copyObj));

kết quả

{"data":"someData","text":"someText","number":"someNumber"}

Object phức tạp, object dạng lồng nhau

Ở dạng lồng nhau kiểu:

let srcObj = {
    value: 1,
    obj: {
        valueChild: 2
    }
};

Với dạng này sử dụng copy bình thường như cách trên thì ta vẫn copy được object đấy, tuy nhiên thứ sao chép được chỉ là những thuộc tính nằm ở lớp đầu tiên của srcObj thôi. Vậy nên nếu thuộc tính lớp đầu tiên này là một object thì nó chỉ copy con trỏ tới object con srcObj.obj đó:

let copyObj = {...srcObj}; // copy theo kiểu phân rã
console.log(JSON.stringify(copyObj)); // in copy ra

srcObj.obj.valueChild = 12345; // thay đổi thuộc tính của lớp con của obj src
console.log(JSON.stringify(copyObj)); // in copy ra lần 2

Kết quả là:
{"value":1,"obj":{"valueChild":2}}

{"value":1,"obj":{"valueChild":12345}}

Thấy chưa, object copy copyObj bị thay đổi giá trị khi thay đổi giá trị ở object nguồn srcObj.
Vì vậy chúng ta khi code javascript cần chú ý về copy object. Nếu object có nhiều tầng mà cứ copy kiểu như vậy thì có thể một ngày nào đó bạn sẽ không biết tại sao dữ liệu tự nhiên bị thay đổi một cách thần kỳ!

Deep copy

Với những ứng dụng thực tế thì các object lồng nhau là chuyện bình thường, đôi lúc chúng ta cần phải copy object như thế thì phải làm thế nào?

  • Tự viết hàm copy object: chúng ta có thể viết hàm duyệt toàn bộ object và copy nội dung của nó từ gốc đến ngọn

  • Sử dụng thư viện chuyên biệt: có một số thư viện làm điều này cho chúng ta và cung cấp hàm để sử dụng một cách đơn giản: lodash (underscore)

  • Sử dụng thư viện Imutable: cũng là thư viện nhưng mình tách thể loại này ra vì nó là thư viện đặc biệt, nhất là với những ai làm ứng dụng có sử dụng redux. Imutable tạo ra object mà ta không thể thay đổi dữ liệu của nó được, mỗi lần thay đổi sẽ tạo ra một object copy mới (thuật toán copy của nó tối ưu, không phải đi copy toàn bộ từ đầu đến cuối).

Chi tiết các thư viện nhắc đến trên đã có đầy đủ tài liệu mạng, trong phạm vi bài này mục đích mình chỉ ra việc cần thận trọng trong việc copy các object lồng nhau thôi.

Mọi thắc mắc xin để lại comment!

comments powered by Disqus