Lập trình · 27/09/2026

JavaScript Number.isFinite: Chặn NaN và Infinity trước khi hiển thị kết quả

Một ô thống kê hiển thị Infinity hoặc NaN dù các biến đầu vào đều có kiểu number. Chỉ kiểm tra typeof chưa đủ để khẳng định một kết quả có thể sử dụng. Với phép tính tỷ lệ, thời lượng hoặc chỉ số dashboard, cần kiểm tra cả đầu vào, điều kiện phép toán và kết quả cuối.

JavaScript Number.isFinite: Chặn NaN và Infinity trước khi hiển thị kết quả

Một ô thống kê hiển thị Infinity hoặc NaN dù các biến đầu vào đều có kiểu number. Chỉ kiểm tra typeof chưa đủ để khẳng định một kết quả có thể sử dụng. Với phép tính tỷ lệ, thời lượng hoặc chỉ số dashboard, cần kiểm tra cả đầu vào, điều kiện phép toán và kết quả cuối.

1. Kiểu number chưa bảo đảm số hữu hạn

Theo tài liệu Number.isFinite của MDN, hàm chỉ chấp nhận giá trị kiểu number hữu hạn; NaN và hai giá trị vô cực đều bị từ chối. Hàm không tự chuyển chuỗi thành số.

console.log(typeof NaN);            // 'number'
console.log(typeof Infinity);       // 'number'
console.log(Number.isFinite(0));    // true
console.log(Number.isFinite(12.5)); // true
console.log(Number.isFinite(NaN));  // false
console.log(Number.isFinite(Infinity)); // false
console.log(Number.isFinite('12')); // false

Đừng dùng kiểm tra truthy để quyết định một số có hợp lệ hay không: số 0 là kết quả hợp lệ trong nhiều chỉ số nhưng bị coi là false khi chuyển sang boolean. Ngược lại, một giá trị vô cực không bị loại chỉ bằng cách kiểm tra truthy.

2. Phân biệt kiểm tra với chuyển đổi

Hàm toàn cục isFinite có bước chuyển đổi kiểu, khác với Number.isFinite. Với dữ liệu API yêu cầu number, cách kiểm tra không chuyển kiểu giúp phát hiện server trả sai hợp đồng thay vì che giấu khác biệt.

console.log(isFinite('12'));        // true
console.log(Number.isFinite('12')); // false
console.log(isFinite(null));        // true
console.log(Number.isFinite(null)); // false

Nếu ứng dụng nhận chuỗi từ biểu mẫu, hãy xây dựng bước đọc và validation riêng. Quyết định có chấp nhận dấu phẩy thập phân, khoảng trắng hay ký hiệu phần trăm hay không trước khi chuyển đổi. Number.isFinite không phải bộ phân tích số theo ngôn ngữ người dùng.

3. Tính tỷ lệ với kết quả có trạng thái rõ ràng

Ví dụ sau dành cho tỷ lệ giữa hai đại lượng không âm, với mẫu số phải lớn hơn 0. Nó không giới hạn kết quả ở 100%: đó là quy tắc nghiệp vụ riêng nếu sản phẩm yêu cầu.

function percentage(part, total) {
  if (!Number.isFinite(part) || !Number.isFinite(total)) {
    return { ok: false, reason: 'invalid-input' };
  }
  if (part < 0 || total <= 0) {
    return { ok: false, reason: 'invalid-range' };
  }

  const value = (part / total) * 100;
  if (!Number.isFinite(value)) {
    return { ok: false, reason: 'non-finite-result' };
  }
  return { ok: true, value };
}

console.log(percentage(0, 10));
// { ok: true, value: 0 }
console.log(percentage(3, 4));
// { ok: true, value: 75 }
console.log(percentage(1, 0));
// { ok: false, reason: 'invalid-range' }

Kiểm tra đầu vào hữu hạn không thay thế kiểm tra đầu ra. Phép tính với những số hữu hạn nhưng có độ lớn chênh lệch cực đoan vẫn có thể cho kết quả vượt khả năng biểu diễn hữu hạn. Hàm cũng không khẳng định độ chính xác tuyệt đối của số thực hoặc phát hiện mọi trường hợp làm tròn về 0.

4. Hiển thị “không tính được” khác với 0%

const result = percentage(1, 0);
const label = result.ok
  ? result.value.toFixed(1) + '%'
  : 'N/A';

Đây là ví dụ chọn chuỗi hiển thị, chưa thao tác DOM. Trong giao diện thật, giải thích N/A bằng nhãn dễ hiểu hoặc thông báo phù hợp. Đừng thay mọi lỗi bằng 0 vì người đọc có thể hiểu đó là một phép đo thật.

Nếu mẫu số bằng 0 biểu thị “chưa có dữ liệu” trong sản phẩm, hãy thể hiện trạng thái đó có chủ đích. Nếu nó cho thấy dữ liệu đầu nguồn bị hỏng, cần ghi nhận lỗi phù hợp. Cùng một phép toán không đủ để quyết định hai tình huống nghiệp vụ này.

5. Những điều isFinite không kiểm tra

  • Số có phải số nguyên hay không: 12.5 vẫn hữu hạn.
  • Số có nằm trong miền nghiệp vụ hay không: -5 vẫn hữu hạn.
  • Số nguyên có nằm trong khoảng biểu diễn an toàn hay không.
  • Đơn vị đo có đồng nhất hay không, chẳng hạn giây so với mili giây.
  • Kết quả có đủ độ chính xác cho yêu cầu ứng dụng hay không.

Vì thế, không dùng một kiểm tra hữu hạn để thay toàn bộ schema và quy tắc nghiệp vụ. Giữ mỗi kiểm tra gần nơi có đủ ngữ cảnh để giải thích và xử lý lỗi.

6. Checklist kiểm thử

Với hàm minh họa, thử các cặp (0, 10), (3, 4), (1, 0), (-1, 10), chuỗi '3' thay cho số 3, NaN và Infinity. Thêm trường hợp độ lớn cực đoan như (Number.MAX_VALUE, Number.MIN_VALUE) để kiểm tra nhánh kết quả không hữu hạn. Xác minh cả reason lẫn trạng thái hiển thị, không chỉ giá trị số.

Kết luận: Number.isFinite là một hàng kiểm tra hữu ích, không phải chứng nhận dữ liệu hoàn toàn đúng. Giữ số 0 hợp lệ, tách lỗi khỏi dữ liệu và kiểm tra kết quả sau phép toán để dashboard không hiển thị một con số gây hiểu nhầm.

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.