Bạn đã bao giờ thấy mệt mỏi khi phải viết từng dòng code để lấy dữ liệu từ mảng hay đối tượng? Destructuring trong JavaScript chính là giải pháp bạn cần. Đây là một cú pháp cực kỳ mạnh mẽ của ES6, giúp bạn “giải nén” giá trị từ các cấu trúc dữ liệu một cách ngắn gọn và dễ đọc hơn rất nhiều. Hãy cùng WiWeb tìm hiểu từ A-Z cách làm chủ kỹ thuật này để tối ưu hóa code của bạn nhé!
Destructuring là gì?
Hãy tưởng tượng bạn có một hộp quà chứa nhiều món đồ. Thay vì phải lấy từng món một cách thủ công, bạn có thể mở toang chiếc hộp và lấy chính xác những gì mình cần. Đó chính là ý tưởng cốt lõi đằng sau Destructuring trong JavaScript.
Định nghĩa Destructuring Assignment trong JavaScript (JS)
Destructuring assignment (phép gán phá vỡ cấu trúc) là một cú pháp đặc biệt cho phép bạn trích xuất dữ liệu từ mảng (arrays) hoặc đối tượng (objects) và gán chúng vào các biến riêng lẻ. Cú pháp này giúp lấy dữ liệu ra một cách trực tiếp và tường minh, thay vì phải truy cập qua chỉ số (index) của mảng hay tên thuộc tính của đối tượng.
Ví dụ, thay vì viết:
const user = { name: 'WiWeb', age: 5 };
const name = user.name;
const age = user.age;
Bạn có thể viết ngắn gọn hơn nhiều:
const user = { name: 'WiWeb', age: 5 };
const { name, age } = user; // Kết quả tương tự!
Bạn thấy không? Code trông sạch sẽ và dễ hiểu hơn hẳn.
Tại sao nên sử dụng Destructuring?
Việc áp dụng javascript destructuring không chỉ là để “cho ngầu”. Nó mang lại những lợi ích rất thực tế:
- Code ngắn gọn hơn: Giảm đáng kể số dòng code cần viết để gán giá trị, đặc biệt với các đối tượng phức tạp.
- Dễ đọc và dễ hiểu: Cú pháp thể hiện rõ ý định của bạn. Người khác đọc code sẽ biết ngay bạn đang muốn lấy những giá trị nào từ cấu trúc dữ liệu.
- Linh hoạt hơn: Dễ dàng lấy ra chỉ những phần tử bạn cần, đặt giá trị mặc định, hoặc gom các phần còn lại vào một biến duy nhất.

Destructuring Mảng (Array Destructuring)
Mảng là một cấu trúc dữ liệu cực kỳ phổ biến. Hãy xem cách array destructuring giúp chúng ta làm việc với chúng hiệu quả hơn nhé.
Cú pháp cơ bản: Gán phần tử mảng vào biến
Cách hoạt động của nó rất đơn giản. Bạn chỉ cần khai báo các biến trong một cặp dấu ngoặc vuông [] ở bên trái của phép gán. Các biến này sẽ nhận giá trị từ các phần tử tương ứng trong mảng ở bên phải.
const colors = ['Red', 'Green', 'Blue'];
// Gán các phần tử vào biến
const [firstColor, secondColor, thirdColor] = colors;
console.log(firstColor); // Output: 'Red'
console.log(secondColor); // Output: 'Green'
Bỏ qua các phần tử không cần thiết
Nếu bạn chỉ cần lấy một vài phần tử và không quan tâm đến những phần tử khác thì sao? Rất đơn giản, bạn chỉ cần dùng dấu phẩy , để bỏ qua chúng.
const scores = [9, 8, 10, 7];
// Chỉ lấy điểm đầu tiên và thứ ba
const [firstScore, , thirdScore] = scores;
console.log(firstScore); // Output: 9
console.log(thirdScore); // Output: 10
Sử dụng toán tử Rest (…) để lấy các phần tử còn lại
Đây là một tính năng cực kỳ hữu ích. Toán tử ...rest cho phép bạn lấy phần tử đầu tiên (hoặc một vài phần tử đầu) và gom tất cả các phần tử còn lại vào một mảng mới. Lưu ý, toán tử rest in destructuring phải luôn được đặt ở cuối cùng.
const fruits = ['Apple', 'Banana', 'Orange', 'Mango', 'Grape'];
const [favoriteFruit, secondFavorite, ...otherFruits] = fruits;
console.log(favoriteFruit); // Output: 'Apple'
console.log(secondFavorite); // Output: 'Banana'
console.log(otherFruits); // Output: ['Orange', 'Mango', 'Grape']
Gán giá trị mặc định (Default Values)
Đôi khi, một mảng có thể không có đủ phần tử như bạn mong đợi. Để tránh việc biến bị gán giá trị undefined, bạn có thể cung cấp một giá trị mặc định.
const settings = ['Dark'];
const [theme = 'Light', fontSize = 16] = settings;
console.log(theme); // Output: 'Dark' (vì có giá trị trong mảng)
console.log(fontSize); // Output: 16 (vì không có giá trị, nên lấy mặc định)

Destructuring Đối tượng (Object Destructuring)
Tương tự như mảng, object destructuring là một công cụ tuyệt vời để làm việc với các đối tượng. Tuy nhiên, nó có một chút khác biệt: thay vì dựa vào vị trí, nó dựa vào tên thuộc tính.
Cách Destructure một đối tượng: Trích xuất thuộc tính
Bạn sử dụng cặp dấu ngoặc nhọn {} ở bên trái phép gán. Tên các biến bên trong {} phải trùng với tên các thuộc tính (keys) của đối tượng bạn muốn trích xuất.
const person = {
firstName: 'John',
lastName: 'Doe',
age: 30
};
// Tên biến phải khớp với tên thuộc tính
const { firstName, age } = person;
console.log(firstName); // Output: 'John'
console.log(age); // Output: 30
Gán vào biến có tên khác (Aliasing)
Nếu bạn muốn gán giá trị của một thuộc tính vào một biến có tên khác thì sao? ES6 destructuring cho phép bạn làm điều này với cú pháp propertyName: newVariableName. Kỹ thuật này gọi là aliasing (đặt bí danh).
const product = {
id: 'P001',
name: 'Laptop',
price: 25000000
};
// Gán 'name' vào biến 'productName'
// Gán 'price' vào biến 'productPrice'
const { name: productName, price: productPrice } = product;
console.log(productName); // Output: 'Laptop'
console.log(productPrice); // Output: 25000000
Gán giá trị mặc định khi thuộc tính không tồn tại
Giống như với mảng, bạn có thể gán giá trị mặc định cho các biến trong trường hợp thuộc tính đó không tồn tại trong đối tượng.
const config = {
server: 'api.wiweb.vn',
port: 8080
};
const { server, port, timeout = 3000 } = config;
console.log(server); // Output: 'api.wiweb.vn'
console.log(timeout); // Output: 3000 (vì 'timeout' không có trong 'config')
Sử dụng toán tử Rest (…) với thuộc tính đối tượng
Toán tử ...rest cũng hoạt động với đối tượng. Nó sẽ tạo ra một đối tượng mới chứa tất cả các thuộc tính còn lại mà bạn không liệt kê ra.
const userProfile = {
id: 123,
username: 'wiweb_master',
email: 'hello@wiweb.vn',
isAdmin: true
};
const { id, ...userInfo } = userProfile;
console.log(id); // Output: 123
console.log(userInfo); // Output: { username: 'wiweb_master', email: 'hello@wiweb.vn', isAdmin: true }

Các Kỹ thuật Destructuring Nâng cao
Khi đã nắm vững những kiến thức cơ bản, bạn có thể kết hợp chúng để xử lý các cấu trúc dữ liệu phức tạp hơn. Đây là lúc sức mạnh của destructuring thực sự tỏa sáng.
Destructuring Lồng nhau (Nested Destructuring) với Mảng và Đối tượng
Thực tế, dữ liệu thường được cấu trúc lồng vào nhau. Bạn có thể áp dụng destructuring theo đúng cấu trúc đó để đi sâu vào bên trong và lấy ra giá trị mình cần một cách trực tiếp.
const user = {
id: 1,
name: 'WiWeb',
contact: {
email: 'hello@wiweb.vn',
address: {
city: 'Hanoi',
country: 'Vietnam'
}
},
skills: ['HTML', 'CSS', 'JavaScript']
};
// Lấy ra email, city và kỹ năng đầu tiên
const {
contact: { email, address: { city } },
skills: [firstSkill]
} = user;
console.log(email); // Output: 'hello@wiweb.vn'
console.log(city); // Output: 'Hanoi'
console.log(firstSkill); // Output: 'HTML'
Cú pháp nested destructuring này trông có vẻ phức tạp lúc đầu, nhưng nó cực kỳ hiệu quả khi bạn đã quen.
Destructuring trong Tham số Hàm (Function Parameters)
Đây là một trong những ứng dụng phổ biến và hữu ích nhất. Thay vì truyền vào một đối tượng options và sau đó phải truy cập options.title, options.width bên trong hàm, bạn có thể destructure ngay tại danh sách tham số.
Cách này giúp code bên trong hàm sạch sẽ hơn và cũng làm rõ những thuộc tính nào mà hàm đang mong đợi từ đối tượng đầu vào.
// Thay vì viết thế này:
function createMenu(options) {
const title = options.title || 'Untitled';
const width = options.width || 200;
// ...
}
// Bạn có thể viết gọn hơn nhiều:
function createMenu({ title = 'Untitled', width = 200, height = 100 }) {
console.log(`Creating menu: ${title} (${width}x${height})`);
}
createMenu({ title: 'File Menu', width: 300 });
// Output: Creating menu: File Menu (300x100)
Việc sử dụng destructuring function parameters làm cho hàm của bạn trở nên tự giải thích (self-documenting) và dễ sử dụng hơn rất nhiều.

Phân biệt Destructuring và Toán tử Spread (…)
Nhiều bạn mới học thường nhầm lẫn giữa cú pháp Destructuring với toán tử Rest ... và toán tử Spread .... Chúng cùng sử dụng ba dấu chấm nhưng mục đích lại hoàn toàn trái ngược nhau.
Sự khác biệt chính: “Gom vào” và “Trải ra”
Đây là cách phân biệt đơn giản nhất:
- Destructuring (với Rest
...): Được sử dụng ở bên trái của phép gán. Nó có tác dụng gom các phần tử/thuộc tính còn lại vào một mảng/đối tượng mới. Giống như bạn đang dọn dẹp và gom đồ vào hộp.const numbers = [1, 2, 3, 4, 5]; const [first, ...rest] = numbers; // Gom 2, 3, 4, 5 vào biến 'rest' - Toán tử Spread
...: Được sử dụng ở bên phải của phép gán hoặc khi truyền tham số cho hàm. Nó có tác dụng trải các phần tử của một mảng/đối tượng ra. Giống như bạn mở một hộp và trải đồ ra.const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5]; // Trải các phần tử của arr1 ra thành [1, 2, 3, 4, 5]
Khi nào dùng Destructuring? Khi nào dùng Spread?
- Dùng Destructuring khi: Bạn muốn trích xuất một hoặc nhiều giá trị từ một mảng hoặc đối tượng để sử dụng chúng trong các biến riêng lẻ.
- Dùng Spread khi: Bạn muốn tạo một bản sao của mảng/đối tượng, hoặc kết hợp nhiều mảng/đối tượng lại với nhau, hoặc truyền các phần tử của một mảng làm tham số cho một hàm.

Ví dụ và Ứng dụng Thực tế của Destructuring
Lý thuyết là vậy, nhưng destructuring thực sự hữu ích ở đâu trong công việc hàng ngày? Hãy cùng xem một vài ví dụ nhé.
Hoán đổi giá trị hai biến (Swapping variables)
Đây là ví dụ kinh điển. Trước đây, để hoán đổi giá trị hai biến, bạn cần một biến tạm. Với destructuring, việc này trở nên vô cùng thanh lịch.
let a = 5;
let b = 10;
// Hoán đổi giá trị chỉ trong một dòng!
[a, b] = [b, a];
console.log(a); // Output: 10
console.log(b); // Output: 5
Trích xuất dữ liệu từ API Response
Khi làm việc với API, bạn thường nhận về một đối tượng JSON lớn, nhưng chỉ cần một vài trường dữ liệu. Destructuring giúp bạn lấy chính xác những gì bạn cần.
// Giả sử đây là dữ liệu trả về từ API
const apiResponse = {
data: {
user: {
id: 123,
name: 'Alice',
email: 'alice@example.com'
}
},
status: 200
};
// Lấy ra name và email một cách dễ dàng
const { data: { user: { name, email } } } = apiResponse;
console.log(`User: ${name}, Email: ${email}`);
// Output: User: Alice, Email: alice@example.com
Tại sao Destructuring lại hữu ích trong React (Destructuring Props)?
Nếu bạn là một lập trình viên React, bạn chắc chắn sẽ yêu thích destructuring. Nó giúp việc xử lý props và state trở nên gọn gàng hơn rất nhiều. Thay vì liên tục viết this.props.name hay props.user, bạn có thể destructure chúng ngay từ đầu.
// Component nhận props
// Thay vì viết: function UserCard(props) { ... props.user.name ... }
function UserCard({ user }) {
// Destructure tiếp đối tượng user bên trong
const { name, avatarUrl } = user;
return (
<div>
<img src={avatarUrl} alt={name} />
<h2>{name}</h2>
</div>
);
}
Việc react destructuring props không chỉ làm code ngắn hơn mà còn giúp bạn biết được component này phụ thuộc vào những props cụ thể nào chỉ bằng cách nhìn vào phần khai báo hàm.

Lời kết
Destructuring là một trong những tính năng mạnh mẽ và hữu ích nhất được giới thiệu trong ES6. Nó không chỉ giúp bạn viết code ít hơn mà còn làm cho code của bạn trở nên rõ ràng, dễ đọc và dễ bảo trì hơn.
Từ việc xử lý mảng, đối tượng, tham số hàm cho đến các ứng dụng thực tế trong React hay khi làm việc với API, việc thành thạo destructuring sẽ nâng cao đáng kể kỹ năng lập trình JavaScript của bạn.
Bạn còn ví dụ hay ho nào về việc sử dụng destructuring không? Hãy chia sẻ trong phần bình luận bên dưới nhé!
Nếu bạn đang tìm kiếm một đơn vị xây dựng website chuyên nghiệp để áp dụng những kỹ thuật lập trình hiện đại, WiWeb luôn sẵn sàng đồng hành. Liên hệ với chúng tôi để được tư vấn nhé!


Bài viết rất chi tiết, nhưng cho mình hỏi một tình huống thực tế: khi destructure một object từ API mà object đó có thể là `null` hoặc `undefined`, thì có cách nào xử lý an toàn để không bị crash app không nhỉ?
Cảm ơn bạn đã đặt một câu hỏi rất thực tế! Để xử lý an toàn, bạn chỉ cần thêm một object rỗng `{}` làm giá trị mặc định như sau: `const { data } = apiResult || {};`. Như vậy, kể cả khi `apiResult` là `null` hay `undefined`, code của bạn vẫn sẽ không bị lỗi.