Trong JavaScript, mảng là đối tượng đặc biệt cho phép lỗ hổng (sparse array) — các chỉ số bị bỏ qua sẽ mang giá trị undefined nhưng không thực sự tồn tại như phần tử mảng. Hiểu cơ chế này giúp tránh bug khi lặp mảng.
Cách tạo undefined holes
Gán giá trị cho chỉ số lớn hơn độ dài hiện tại của mảng:
const nums = [1, 2, 3]; // length = 3
nums[5] = 6; // Chỉ số 5 > 2 (chỉ số cuối)
// Kết quả: nums = [1, 2, 3, empty × 2, 6]
// Chỉ số 3 và 4 là "holes" (lỗ rỗng)
Ví dụ hoàn chỉnh
<html>
<body>
<script>
var nums = [1, 2, 3];
nums[5] = 6; // Tạo hole tại index 3, 4
var len = nums.length; // 6
var text = "";
for (var i = 0; i < len; i++) {
text += nums[i] + "<br>";
}
document.write(text);
// Kiểm tra thêm
document.write("<br>length: " + nums.length); // 6
document.write("<br>3 in nums: " + (3 in nums)); // false (hole)
document.write("<br>nums[3]: " + nums[3]); // undefined
document.write("<br>nums.hasOwnProperty(3): " + nums.hasOwnProperty(3)); // false
</script>
</body>
</html>
Kết quả đầu ra
1 2 3 undefined undefined 6 length: 6 3 in nums: false nums[3]: undefined nums.hasOwnProperty(3): false
Đặc điểm quan trọng của holes
| Phép toán | Hành vi với holes |
|---|---|
for (let i=0; i<arr.length; i++) | Duyệt qua holes, arr[i] trả về undefined |
for...of | Bỏ qua holes (chỉ duyệt phần tử thực) |
forEach, map, filter, reduce | Bỏ qua holes |
arr.includes(val) | Kiểm tra holes như undefined |
arr.indexOf(val) | Tìm thấy undefined tại hole |
Object.keys(arr) | Chỉ liệt kê chỉ số có phần tử thực |
JSON.stringify(arr) | Holes thành null |
Cách xóa holes (làm mảng dENSE)
// Cách 1: filter Boolean (cũng xóa 0, "", false, null)
const dense = arr.filter(Boolean);
// Cách 2: spread + filter giữ undefined
const dense = [...arr].filter(x => x !== undefined);
// Cách 3: Array.from (biến hole thành undefined thực)
const dense = Array.from(arr);
// Cách 4: fill rồi filter (nếu biết trước giá trị fill)
const dense = arr.fill(0).filter(x => x !== 0);
Lưu ý thực tế
- Holes làm
lengthtăng nhưng không tăng bộ nhớ cho các phần tử thiếu. - Tránh tạo holes vô tình — hãy dùng
push,splice, hoặc khởi tạo đầy đủ. - Khi nhận mảng từ API/bên ngoài, hãy
Array.from(arr)hoặc[...arr]để chuẩn hóa trước khi xử lý.