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

JavaScript ?? và ||: Chọn giá trị mặc định mà không làm mất số 0

Người dùng chọn số lần thử lại bằng 0 nhưng ứng dụng vẫn dùng 3. Một nguyên nhân dễ bỏ qua là biểu thức retries || 3 đã coi 0 như lý do để lấy mặc định. Khi dữ liệu có các giá trị hợp lệ như 0 hoặc false, cách chọn mặc định cần phản ánh đúng ý nghĩa nghiệp vụ.

JavaScript ?? và ||: Chọn giá trị mặc định mà không làm mất số 0

Người dùng chọn số lần thử lại bằng 0 nhưng ứng dụng vẫn dùng 3. Một nguyên nhân dễ bỏ qua là biểu thức retries || 3 đã coi 0 như lý do để lấy mặc định. Khi dữ liệu có các giá trị hợp lệ như 0 hoặc false, cách chọn mặc định cần phản ánh đúng ý nghĩa nghiệp vụ.

1. Thiếu giá trị không giống falsy

Theo tài liệu toán tử ?? của MDN, vế phải được dùng khi vế trái là null hoặc undefined. Trong khi đó, || dùng vế phải với mọi giá trị falsy, bao gồm 0, false và chuỗi rỗng.

const settings = { retries: 0, enabled: false };

console.log(settings.retries || 3); // 3
console.log(settings.retries ?? 3); // 0
console.log(settings.enabled ?? true); // false

Các chú thích là kết quả mong đợi. Ví dụ giả định 0 nghĩa là không thử lại và false nghĩa là chủ động tắt tính năng. Nếu sản phẩm không cho phép những giá trị này, cần validation riêng thay vì dựa vào toán tử mặc định.

2. Chọn chính sách cho từng trường

Dữ liệuCâu hỏi cần trả lời
Số lần thử lại bằng 0Có phải lựa chọn tắt retry hợp lệ không?
Nhãn là chuỗi rỗngNgười dùng muốn bỏ nhãn hay chưa nhập?
Giá trị nullChưa có dữ liệu hay chủ động xóa giá trị?

Không thay toàn bộ || bằng ?? theo kiểu tìm và thay thế. Có nơi nghiệp vụ thực sự muốn dùng nhãn mặc định cho chuỗi rỗng; có nơi phải giữ chuỗi rỗng. Ghi lại quyết định trước khi sửa mã.

3. Mặc định không thay thế kiểm tra kiểu

function normalizeRetries(value) {
  const retries = value ?? 3;
  if (!Number.isInteger(retries) || retries < 0 || retries > 10) {
    throw new TypeError('Expected an integer from 0 to 10');
  }
  return retries;
}

Đây là chính sách minh họa: thiếu giá trị thì dùng 3; có giá trị thì phải là số nguyên từ 0 đến 10. Chuỗi "3", false và NaN bị từ chối. Giới hạn 10 không phải chuẩn chung; hãy thay bằng giới hạn của hệ thống.

Không ép kiểu tùy tiện chỉ để validation đi qua. Dữ liệu từ biểu mẫu hoặc biến môi trường có thể là chuỗi và cần bước phân tích đầu vào rõ ràng trước khi gọi hàm này.

4. Giữ biểu thức dễ đọc

Không kết hợp trực tiếp ?? với || hoặc && nếu không có ngoặc. Nhưng thêm ngoặc chỉ giải quyết cú pháp, không chứng minh quy tắc đã đúng. Nếu biểu thức có nhiều tầng mặc định, tách thành biến có tên mô tả để người review hiểu thứ tự ưu tiên.

Vế phải của ?? chỉ được đánh giá khi cần. Nếu nó là lời gọi hàm, đừng dựa vào tác dụng phụ của hàm đó để làm một công việc bắt buộc luôn phải chạy.

5. Checklist kiểm thử

  • Thử riêng undefined, null, 0, false và chuỗi rỗng.
  • Thử giá trị đúng kiểu nhưng ngoài miền cho phép.
  • Kiểm tra dữ liệu chuỗi từ API hoặc biểu mẫu.
  • Xác nhận mặc định không ghi đè lựa chọn tắt của người dùng.
  • Đặt test cho các trường hợp từng bị nhầm giữa thiếu dữ liệu và số 0.

Toán tử tốt là toán tử thể hiện đúng chính sách. Dùng ?? khi chỉ null và undefined cần mặc định, và giữ validation như một bước độc lập.

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.