Trong JavaScript, sao chép mảng không đơn giản như dùng toán tử gán (=) tạo bản sao. Nếu bạn từng thử, bạn sẽ ngạc nhiên thấy nó chỉ tạo liên kết đến danh sách gốc. Vấn đề là gì?
Trong hướng dẫn này, chúng ta sẽ nói về cách sao chép mảng JavaScript. Chúng ta sẽ đi qua mã cho ba chiến lược sao chép mảng JavaScript để bạn bắt đầu sao chép mảng.
Vấn đề sao chép mảng JavaScript
Ở một mức độ nào đó, toán tử "=" tạo bản sao mảng vào biến mới. Nó giống con trỏ hơn là bản sao. Đó là vì "=" tạo tham chiếu đến mảng gốc. Nó không tạo bản sao của mảng hiện có.
Hãy thử tạo bản sao mảng dùng toán tử gán không có mã khác:
var berries = ["Strawberry", "Gooseberry", "Raspberry"]; var fruits = berries; console.log(fruits);
Mã trả về:
[ "Strawberry", "Gooseberry", "Raspberry" ]
Trông như mảng đã được sao chép. "fruits" chứa tất cả giá trị từ mảng "berries".
Bây giờ, thử thêm mục vào mảng "fruits":
fruits.push("Melon"); console.log(fruits); console.log(berries);
Chúng ta thêm "Melon" vào mảng fruits. Sau đó in giá trị "fruits" và "berries" ra console:
[ "Strawberry", "Gooseberry", "Raspberry", "Melon" ] [ "Strawberry", "Gooseberry", "Raspberry", "Melon" ]
Cả "fruits" và "berries" chứa cùng giá trị. Đó là vì chúng ta chưa sao chép mảng về mặt kỹ thuật. Chỉ tạo tham chiếu đến nó.
Bất cứ khi nào thao tác mảng "berries", thay đổi sẽ làm trong mảng "fruits".
Cách sao chép mảng JavaScript
Toán tử gán không sao chép mảng. Chúng ta phải dùng cách khác. May mắn cho chúng ta, có nhiều cách tạo bản sao mảng. Ba cách hàng đầu:
- Dùng toán tử spread (spread operator)
- Dùng vòng lặp for
- Dùng Array.from
Hãy thảo luận từng cái.
Dùng toán tử Spread
Toán tử spread là tính năng giới thiệu trong JavaScript ES6. Cho phép truy cập nội dung đối tượng lặp được. Toán tử thường dùng tạo bản sao nông (shallow copy) của mảng.
Toán tử spread gồm ba chấm, giống dấu ba chấm (…). Hãy thử tạo bản sao mảng "berries" từ trước:
var berries = ["Strawberry", "Gooseberry", "Raspberry"]; var fruits = [...berries]; fruits.push("Melon");
Chúng ta dùng toán tử spread tạo bản sao mảng. Kiểm tra giá trị mảng đảm bảo đúng:
console.log(berries); console.log(fruits);
Mã trả về:
[ "Strawberry", "Gooseberry", "Raspberry" ] [ "Strawberry", "Gooseberry", "Raspberry", "Melon" ]
Giá trị "Melon" chỉ thêm vào mảng "fruits". Đó là vì dùng toán tử spread tạo bản sao của "berries". Bây giờ, "fruits" là mảng riêng. Giá trị tách biệt khỏi "berries".
Dùng vòng lặp for
Phương pháp thử và đúng, dùng vòng lặp for là cách tốt tạo bản sao mảng.
Phương pháp này có thể không được ưu tiên như spread operator vì cần nhiều dòng mã hơn. Tuy nhiên, vòng lặp for sao chép đối tượng tốt.
var berries = ["Strawberry", "Gooseberry", "Raspberry"]; var fruits = []; for (var i = 0; i < berries.length; i++) { fruits[i] = berries[i] }
Chúng ta khai báo hai danh sách: berries và fruits. Fruits ban đầu danh sách rỗng. Sau đó, dùng vòng lặp for lặp qua mỗi mục "berries". Với mỗi mục, giá trị sao chép sang mảng "fruits".
Chạy kiểm tra xem mảng có tách biệt:
fruits.push("Grapefruit"); console.log(berries); console.log(fruits);
Mã trả về:
[ "Strawberry", "Gooseberry", "Raspberry" ] [ "Strawberry", "Gooseberry", "Raspberry", "Grapefruit" ]
Thành công! "berries" và "fruits" là hai mảng riêng biệt.
Dùng Array.from()
Phương thức Array.from() biến bất kỳ đối tượng lặp được thành mảng. Nó đi qua mỗi mục trong đối tượng lặp và nối vào mảng mới. Nghĩa là nó dùng được để sao chép mảng.
Hãy tạo bản sao mảng "berries" lại:
var berries = ["Strawberry", "Gooseberry", "Raspberry"]; var fruits = Array.from(berries);
Giải pháp này, giống cú pháp spread operator, chỉ chiếm hai dòng mã. Cách hiệu quả và ngắn gọn sao chép mảng. Bây giờ chạy kiểm tra mảng mới:
fruits.push("Pineapple"); console.log(berries); console.log(fruits);
Mã trả về:
[ "Strawberry", "Gooseberry", "Raspberry" ] [ "Strawberry", "Gooseberry", "Raspberry", "Pineapple" ]
Mảng đã sao chép thành công.
Kết luận
Sao chép mảng trong JavaScript dễ khi bạn biết cách.
Toán tử gán không đủ sao chép mảng nếu muốn tạo phiên bản riêng của mảng. Vì toán tử gán tạo con trỏ đến mảng hiện có; không tạo mảng mới.
Bạn có thể tạo bản sao mảng dùng toán tử spread, vòng lặp for, hoặc phương thức Array.from(). Bây giờ bạn sẵn sàng sao chép mảng trong JavaScript như chuyên gia.