Câu 1Viết const copied = [...items];, rồi copied.push("X"). Chuyện gì xảy ra với items gốc?
Spread Syntax — Sao Chép, Kết Hợp, và Ghi Đè Cài Đặt
Học spread syntax: bung nội dung mảng hay object ra tại chỗ để sao chép và gộp mà không đổi bản gốc.
Gộp một danh sách sản phẩm còn hàng với một danh sách đặt trước thành một. Chỉ xếp chồng các trường người dùng đã đổi lên trên cài đặt mặc định. Trong các trường hợp như thế này, bạn xây một mảng hay object mới với nội dung được trải ra, trong khi giữ dữ liệu gốc đúng như nó vốn có.
Bài này nói về spread syntax cho việc đó, và giá trị nào thắng khi cùng một key xuất hiện hai lần.
Trải Nội Dung Ra Tại Chỗ — Spread Syntax
Muốn gộp một danh sách sản phẩm còn hàng với một danh sách đặt trước thành một? Thêm từng cái bằng push, và mảng gốc bị ghi đè. Đây là trường hợp bạn muốn xây một mảng mới với nội dung được trải ra, trong khi giữ các danh sách gốc đúng như chúng vốn có.
Spread syntax (viết ... trước một giá trị để trải nội dung của mảng hay object ra tại chỗ) cho phép bạn viết const allItems = [...inStock, ...backOrder]; để xây một mảng mới, đã gộp. Chỉ viết một cái, như [...inStock], và đó là một bản sao — một mảng riêng với cùng nội dung.
Object hoạt động giống vậy, với { ...product }. Lưu ý đây là một bản sao chỉ ở cấp đầu tiên — hành vi khi có một object hay mảng lồng bên trong sẽ nói ở bài về tham chiếu và sao chép.
... đóng vai trò khác nhau tùy vào chỗ bạn viết nó. Ở bên trái của =, nó là rest, gộp phần còn dư. Trong [] hay {} ở bên phải, nó là spread, trải nội dung ra. Cùng một ký hiệu, nhưng gộp và trải chạy theo hướng ngược nhau.
const inStock = ["Wireless Mouse", "USB-C Hub"];
const backOrder = ["Monitor Arm"];
// Xây một mảng mới trải cả hai
const allItems = [...inStock, ...backOrder];
console.log(allItems.join(", ")); // Wireless Mouse, USB-C Hub, Monitor Arm
// Mảng gốc không đụng tới
console.log(inStock.length); // 2
// Bạn có thể trộn một giá trị riêng lẻ vào giữa
const featured = ["This Week's Pick", ...inStock];
console.log(featured.length); // 3
// Object cũng sao chép được theo cùng cách
const product = { name: "USB-C Hub", price: 2480 };
const copied = { ...product };
console.log(copied.price); // 2480
Xếp Chồng Cài Đặt — Giá Trị Viết Sau Thắng
Cài đặt của một ứng dụng đôi khi được thiết lập với một vòng mặc định đầy đủ, rồi chỉ những trường người dùng đã đổi mới bị ghi đè lên. Kiểm tra và gán từng trường đã đổi một lần lượt, tuy nhiên, và bạn sẽ cần thêm code mỗi khi một cài đặt mới xuất hiện.
Xếp hai object spread cạnh nhau, như { ...defaultSettings, ...userSettings }, và một key chung sẽ bị ghi đè bởi giá trị nào được viết sau. Một key người dùng chưa chỉ định giữ nguyên ở mặc định.
Thứ tự bạn viết chúng trực tiếp trở thành mức ưu tiên, nên đặt mặc định trước và cái bạn muốn ưu tiên sau.
const defaultSettings = { theme: "light", itemsPerPage: 20, notifications: true };
const userSettings = { theme: "dark" };
const merged = { ...defaultSettings, ...userSettings };
console.log(merged.theme); // dark (cái viết sau thắng)
console.log(merged.itemsPerPage); // 20 (thiếu ở phía người dùng, nên mặc định giữ nguyên)
// Đảo thứ tự, và mặc định thắng thay vào đó
const reversed = { ...userSettings, ...defaultSettings };
console.log(reversed.theme); // light
// Ngay cả một giá trị undefined cũng ghi đè, miễn key tồn tại ở phía sau
const partial = { theme: undefined };
const broken = { ...defaultSettings, ...partial };
console.log(broken.theme); // undefined
Ngay Cả undefined Cũng Ghi Đè
Miễn là key tồn tại ở phía bạn đang xếp chồng lên, nó ghi đè — ngay cả khi giá trị là undefined. Xếp chồng một trường chưa điền thẳng từ một form lên như vậy, và mặc định biến mất, thay bằng undefined. Với một trường bạn chỉ muốn dùng khi nó thực sự có giá trị, kiểm tra từng cái một, như userSettings.theme ?? defaultSettings.theme.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Với const merged = { ...defaults, ...user };, chuyện gì xảy ra với một key tồn tại ở cả hai bên?
Câu 3Object bạn đang xếp chồng lên có key đó, nhưng giá trị của nó là undefined. Chuyện gì xảy ra với mặc định?