Tham chiếu và cloning

Tham chiếu Object

Khi gán lại object bởi một biến khác thì các biến này đều là tham chiếu tới object thật. Khi thay đổi nội dung của object qua một biến thì các biến còn lại cũng bị ảnh hưởng.

1
2
3
4
5
6
7
8
9
var user = {
  name: 'Bill Gates',
  age: 50
};
var bill = user; // bill và user cùng tham chiếu tới một object
console.log(bill === user); // true

bill.name = 'Bill'; // thay đổi biến bill
console.log(user.name); // in ra Bill do biến user cũng thay đổi theo

Object cloning

Nhân bản (cloning) object là tạo một object giống object trước đó. Vì toán tử gán chỉ tham chiếu tới object, muốn tạo tạo object nhân bản chúng ta phải dùng cách khác. Trong trường hợp object không lồng nhau, chúng ta có thể lặp qua một đối tượng để lấy các thuộc tính nhằm tạo object mới.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var user = {
  name: 'Bill Gates',
  age: 50
};
var cloneUser = {};

// lặp qua các thuộc tính 
// và copy các cặp thuộc tính/giá trị
for (let key in user) {
  cloneUser[key] = user[key];
}

console.log(cloneUser); // { name: 'Bill Gates', age: 50 }
console.log(cloneUser === user); // false

Cách khác là sử dụng Object.assign, hàm này cũng lặp qua các thuộc tính của đối tượng và copy các thuộc tính như ví dụ ở trên. Tham số của hàm là object khởi tạo, và object mà chúng ta muốn copy các thuộc tính qua.

1
2
3
4
5
var user = {
  name: 'Bill Gates',
  age: 50
};
var cloneUser = Object.assign({}, user);

Cách mới nhất là dùng toán tử spare operator (được sử dụng từ phiên bản ES2015 trở đi).

1
2
3
4
5
6
7
var user = {
  name: 'Bill Gates',
  age: 50
};
var cloneUser = {
  ... user
};

Deep cloning

Trong trường hợp muốn clone object lồng nhau thì không sử dụng cách trên được. Cách phổ biến là sử dụng hàm cloneDeep từ các thư viện như Lodash.

Hoặc trong ví dụ sau chúng ta sử dụng với thư viện JSON.

1
2
3
var objects = [{ 'a': 1 }, { 'b': 2 }];
var cloningObject = JSON.parse(JSON.stringify(objects));
console.log(objects[0] === cloningObject[0]); // faslse

Tuy nhiên cách này có nhiều hạn chế, ví dụ như không clone được các hàm trong Object.