JavaScript object là một cấu trúc dữ liệu mà bao gồm các cặp giá trị khóa-giá trị (key: value). Các object trong JavaScript là các đối tượng lớn hơn và bao gồm nhiều thuộc tính hơn các biến thông thường, và chúng có thể chứa nhiều loại dữ liệu khác nhau như số, chuỗi, mảng, object khác, hàm, v.v.



Để tạo một object trong JavaScript, bạn có thể sử dụng cú pháp sau:


const objectName = {
 key1: value1,
 key2: value2,
 ...
};


Ví dụ, để tạo một object chứa thông tin về một người dùng, bạn có thể sử dụng cú pháp như sau:

const user = {
  name: 'John Smith',
  age: 30,
  email: 'john@example.com',
  hobbies: ['reading', 'swimming']
};

Sau đó, bạn có thể truy cập các thuộc tính của object bằng cách sử dụng toán tử . hoặc sử dụng cú pháp object[key] để truy cập vào thuộc tính có tên là key. Ví dụ, để lấy giá trị của thuộc tính name trong object user trên, bạn có thể sử dụng các cú pháp sau:

console.log(user.name); // John Smith
console.log(user['name']); // John Smith


Bạn cũng có thể thay đổi giá trị của các thuộc tính trong object bằng cách gán giá trị mới cho chúng. Ví dụ, để thay đổi giá trị của thuộc tính age trong object user thành 35, bạn có thể sử dụng cú pháp sau:

user.age = 35;

Objects trong JavaScript cũng có thể chứa các hàm, được gọi là methods. Để tạo một method trong object, bạn có thể gán một hàm cho một thuộc tính trong object. Ví dụ, để tạo một method cho object user cho phép in ra thông tin người dùng, bạn có thể sử dụng cú pháp sau:

const user = {
  name: 'John Smith',
  age: 30,
  email: 'john@example.com',
  hobbies: ['reading', 'swimming'],
  printInfo: function() {
    console.log(`Name: ${this.name}`);
    console.log(`Age: ${this.age}`);
    console.log(`Email: ${this.email}`);
    console.log(`Hobbies: ${this.hobbies.join(', ')}`);
  }
};

user.printInfo(); // in ra thông tin người dùng


Trong ví dụ trên, hàm printInfo là một method của object user và có thể được gọi bằng cách sử dụng toán tử . như user.printInfo(). Trong method này, từ khóa this đại diện cho object hiện tại, nên có thể truy cập các thuộc tính của object bằng cách sử dụng this.propertyName.

Objects trong JavaScript cũng có thể kế thừa từ nhau bằng cách sử dụng từ khóa extends. Ví dụ, để tạo một object mới admin kế thừa từ object user, bạn có thể sử dụng cú pháp sau:

class Admin extends User { 
// khai báo các thuộc tính và methods cho object Admin 
} 
const admin = new Admin();


Trong ví dụ trên, object admin sẽ kế thừa tất cả các thuộc tính và methods của object user, ngoài ra bạn cũng có thể thêm thêm các thuộc tính và methods riêng cho object admin trong khối khai báo của nó.


Deep copy


Khác với các kiểu dữ liệu cơ bản, Kiểu Object này thì phức tạp hơn kiểu tham trị và được dùng cho các kiểu dữ liệu phức tạp: Object, Array, Function. Ở đây khi gán cho nó một giá trị thì nó không lưu lại giá trị này mà thực chất nó lưu lại địa chỉ của ô nhớ lưu giá trị này. Do vậy khi bạn copy môt object thì chỉ là đang tham chiếu tới ô nhớ của object đó, giả sử có nhiều biến đang cùng tham chiếu tới một object, một biết vô tình update vào object đó thì những biến khác cũng sẽ nhân giá trị mới thay vì giá trị ban đầu bạn muốn. Đây không phải chuyện đùa đây là một trải nghiệm đắng cay.


Ví dụ mình có `user` ở trên. và giờ gán cho một biến `staff` khác:

const staff = user;
staff.age = 33;


xong giờ `staff.age` là 33 và cả `user.age` cũng là 33. Wow! This is nightmare!


Để làm chắc chắn chúng ta nên copy object một cách hoàn toàn `deep` copy.


Deep copy là một kỹ thuật cho phép bạn sao chép một object hoặc mảng và tất cả các phần tử con của nó, không bao gồm bất kỳ liên kết nào đến các phần tử gốc. Điều này có nghĩa là bạn sẽ có một bản sao độc lập của object hoặc mảng gốc, không bị ảnh hưởng bởi bất kỳ thay đổi nào trên object hoặc mảng gốc.


Đây là một số cách thông dụng để thực hiện deep copy trong JavaScript:


1, Sử dụng lodash.cloneDeep();

const _ = require('lodash'); 
const staff = _.cloneDeep(user);


2, Sử dụng recursive function;

Bạn cũng có thể tự viết một hàm đệ quy để thực hiện deep copy cho một object hoặc mảng. Điều này có thể khá phức tạp.

function deepCopy(obj) {
  if (typeof obj !== 'object') return obj;
  if (obj === null) return null;


  let copy;
  if (Array.isArray(obj)) {
    copy = [];
    for (const item of obj) {
      copy.push(deepCopy(item));
    }
  } else {
    copy = {};
    for (const key in obj) {
      copy[key] = deepCopy(obj[key]);
    }
  }


  return copy;
}


const staff = deepCopy(user);


3, Sử dụng `JSON.parse()` và `JSON.stringify()`;

Trùm cuối, nhanh, gọn, đơn giản.

const staff = JSON.parse(
   JSON.stringify(user)
);