Lập trình · 20/10/2026

delete phần tử mảng JavaScript: vì sao length không giảm?

Xóa một dòng bằng delete rows[1] nhưng bộ đếm vẫn báo ba phần tử. Toán tử delete xóa thuộc tính chỉ mục, không dồn các phần tử phía sau và không giảm length. Nếu mục tiêu là bỏ một dòng khỏi danh sách liên tục, cần chọn thao tác khác.

delete phần tử mảng JavaScript: vì sao length không giảm?

Xóa một dòng bằng delete rows[1] nhưng bộ đếm vẫn báo ba phần tử. Toán tử delete xóa thuộc tính chỉ mục, không dồn các phần tử phía sau và không giảm length. Nếu mục tiêu là bỏ một dòng khỏi danh sách liên tục, cần chọn thao tác khác.

1. delete để lại một ô trống

const rows = ['A', 'B', 'C'];
delete rows[1];
console.log(rows.length); // 3
console.log(Object.hasOwn(rows, 1)); // false
console.log(rows[2]); // C
console.log(rows[1]); // undefined

Ví dụ tự kiểm chứng cho thấy C vẫn nằm ở chỉ mục 2. Đọc vị trí 1 trả undefined trong mảng thông thường này, nhưng thuộc tính ở vị trí đó đã không còn. Vì vậy, length không phải số ô thực sự được gán giá trị trong một mảng thưa.

Không suy ra rằng giao diện đã xóa đúng chỉ vì phần tử bị mất khi render. Cấu trúc dữ liệu còn ô trống có thể ảnh hưởng tới bước xử lý tiếp theo.

2. Gán undefined vẫn giữ phần tử

const absent = ['A', 'B'];
delete absent[1];
const explicit = ['A', 'B'];
explicit[1] = undefined;
console.log(Object.hasOwn(absent, 1)); // false
console.log(Object.hasOwn(explicit, 1)); // true
let visits = 0;
absent.forEach(() => visits++);
console.log(visits); // 1
visits = 0;
explicit.forEach(() => visits++);
console.log(visits); // 2

Hai mảng có cùng length và cùng trả undefined khi đọc vị trí cuối, nhưng callback được gọi số lần khác nhau. Các ví dụ giả định không có thuộc tính chỉ mục kế thừa. Khi kiểm thử dữ liệu danh sách, kiểm tra cả cấu trúc và hành vi duyệt, không chỉ giá trị đọc ra.

3. splice dồn phần tử và sửa mảng nguồn

const rows = ['A', 'B', 'C'];
const alias = rows;
const removed = rows.splice(1, 1);
console.log(JSON.stringify(rows)); // ["A","C"]
console.log(JSON.stringify(removed)); // ["B"]
console.log(alias.length); // 2

splice trả về mảng các phần tử bị lấy ra. rows là danh sách còn lại; alias cũng thấy thay đổi vì giữ cùng tham chiếu. Đừng gán rows = rows.splice(...) với kỳ vọng rows nhận phần danh sách còn lại.

Nếu vị trí đến từ findIndex, phải xử lý kết quả -1 trước khi gọi splice. Chỉ mục âm có ý nghĩa riêng và có thể khiến phần tử cuối bị xóa ngoài dự kiến.

4. Tạo danh sách mới với chỉ mục đã kiểm tra

Helper sau dành cho mảng thông thường, yêu cầu chỉ mục nguyên nằm trong phạm vi. Nó từ chối -1, số thập phân và chuỗi số. Kết quả là mảng mới; các object bên trong vẫn dùng chung tham chiếu với nguồn.

function withoutIndex(rows, index) {
  if (!Array.isArray(rows)) throw new TypeError('Array required');
  if (!Number.isInteger(index) || index < 0 || index >= rows.length) {
    throw new RangeError('Index outside array');
  }
  return rows.slice(0, index).concat(rows.slice(index + 1));
}
const original = [{ id: 'a' }, { id: 'b' }, { id: 'c' }];
const next = withoutIndex(original, 1);
console.log(next.map(row => row.id).join(',')); // a,c
console.log(original.length); // 3
console.log(next === original); // false
console.log(next[0] === original[0]); // true

Hàm không kiểm tra hoặc sửa các ô trống đã có sẵn ở những vị trí khác. Nếu nghiệp vụ yêu cầu mảng đặc, validation đầu vào phải bảo đảm điều đó. Khi cần sửa object của một dòng mà không ảnh hưởng nguồn, tạo bản sao ở đúng tầng dữ liệu cần thay đổi.

5. Kiểm tra kết quả xóa theo mục tiêu

  • length có giảm đúng một và phần tử kế tiếp có dịch vị trí không?
  • Mảng nguồn cần thay đổi hay phải được giữ nguyên?
  • Kết quả trả về là phần bị xóa hay danh sách còn lại?
  • Chỉ mục không tìm thấy có bị chặn không?
  • Object trong mảng mới có còn chia sẻ tham chiếu không?

Tám khối ví dụ Việt–Anh đã chạy bằng Node.js, kèm kiểm tra xóa đầu, giữa, cuối và chỉ mục sai cho helper. Chưa kiểm thử component giao diện. Tham khảo MDN delete và MDN Array.splice.

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.