Trạng thái có vẻ là 1 nhưng switch lại đi vào default, hoặc chọn một nhánh mà hai thao tác cùng chạy. Hai lỗi này thường đến từ kiểu dữ liệu đầu vào và điểm kết thúc mỗi case. Kiểm tra chúng riêng giúp tránh sửa nhầm logic nghiệp vụ.
1. Chuỗi '1' không khớp case 1
function label(value) {
switch (value) {
case 1: return 'active';
case 0: return 'inactive';
default: return 'unknown';
}
}
console.log(label('1')); // unknown
console.log(label(1)); // active
switch so khớp theo strict equality, không tự đổi chuỗi thành số. Xem MDN switch. Khi giá trị đến từ form hoặc API, hãy kiểm tra kiểu thực tế trước khi thêm một case khác để “chữa cháy”.
Ví dụ label không thực hiện chuyển đổi; đó là lựa chọn có chủ đích. Nếu contract yêu cầu số mà nguồn gửi chuỗi, có thể từ chối dữ liệu hoặc chuyển đổi tại ranh giới nhập liệu theo quy tắc rõ ràng. Đừng rải nhiều cách chuyển đổi khác nhau vào từng nhánh.
2. Khớp một case không tự dừng ở case tiếp theo
const events = [];
switch ('preview') {
case 'preview':
events.push('render preview');
case 'publish':
events.push('send publish');
break;
default:
events.push('unsupported');
}
console.log(events.join('|')); // render preview|send publish
Không có break sau thao tác preview, nên thực thi tiếp phần thân case publish. Đoạn này chỉ ghi vào mảng để tái hiện lỗi, không xuất bản dữ liệu thật. Nhãn publish không được so khớp lại để quyết định có chạy phần thân đó hay không.
Đây là lý do test nên kiểm tra cả thao tác không được phép xảy ra: chọn preview thì số lần gọi publish phải bằng 0. Chỉ xác nhận đã render preview sẽ bỏ sót lỗi thứ hai.
3. Dùng return khi hàm chỉ cần trả một kết quả
function actionFor(value) {
if (typeof value !== 'string') throw new TypeError('action must be a string');
switch (value) {
case 'preview':
return 'render preview';
case 'publish':
return 'send publish';
case 'cancel':
case 'close':
return 'dismiss';
default:
throw new RangeError('unsupported action');
}
}
console.log(actionFor('preview')); // render preview
console.log(actionFor('close')); // dismiss
Ví dụ phân tách đầu vào sai kiểu với giá trị chuỗi chưa hỗ trợ. Hai nhãn cancel và close được nhóm có chủ đích vì chúng dùng chung một kết quả. Không tự trim hoặc đổi chữ hoa trong hàm này; nếu sản phẩm cho phép, ghi rõ quy tắc và kiểm tra nó ở bước tiếp nhận dữ liệu.
return thoát hàm, còn break không nhãn thoát switch gần nhất hoặc vòng lặp gần nhất chứa nó. Nếu còn công việc cần chạy sau switch trong cùng hàm, chọn cấu trúc phù hợp thay vì thay mọi break bằng return một cách máy móc.
4. Bọc từng nhánh nếu cần khai báo biến cùng tên
function describe(kind) {
switch (kind) {
case 'text': {
const result = 'plain text';
return result;
}
case 'image': {
const result = 'image file';
return result;
}
default:
return 'unknown';
}
}
console.log(describe('text')); // plain text
console.log(describe('image')); // image file
Nhãn case không tự tạo block scope riêng. Cặp ngoặc nhọn trong ví dụ giúp mỗi result thuộc một block khác nhau. Khai báo const result hai lần trực tiếp trong cùng thân switch gây SyntaxError, kể cả khi dự kiến chỉ chạy một case. Quy tắc lexical declarations và thực thi case nằm trong ECMAScript switch statement.
5. Review bằng bảng đầu vào và tác dụng phụ
- Thử số, chuỗi tương ứng, null và giá trị chưa hỗ trợ.
- Ghi rõ nhánh nào được phép dùng chung thân xử lý.
- Kiểm tra mỗi nhánh kết thúc bằng break, return hoặc throw theo mục đích.
- Test một lựa chọn không kích hoạt thao tác của lựa chọn khác.
- Dùng block riêng khi case có biến cục bộ.
Tám khối mã Việt–Anh đã chạy bằng Node.js. Kiểm tra bổ sung gồm sai kiểu, chuỗi chưa hỗ trợ và lỗi cú pháp khai báo trùng. Đây là kiểm thử logic trong bộ nhớ, chưa tích hợp form, API hoặc thao tác xuất bản thực tế.




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