Đổi chữ thường thành chữ hoa không bảo đảm giữ nguyên độ dài hoặc khôi phục được văn bản ban đầu. Nếu dùng kết quả đổi hoa thường làm khóa tra cứu, vị trí highlight hay dữ liệu lưu trữ, ứng dụng cần một contract cụ thể hơn thao tác gọi toUpperCase().
1. Một ký tự có thể thành nhiều ký tự
const original = '\u00DF'; // ß
const upper = original.toUpperCase();
console.log(original.length); // 1
console.log(upper); // SS
console.log(upper.length); // 2
console.log(upper.toLowerCase() === original); // false
Trong ví dụ, ß trở thành SS. Đổi ngược về chữ thường cho ss, không trở lại dữ liệu gốc. toUpperCase trả chuỗi mới; xem MDN String.toUpperCase. Đừng dùng một lần đổi hoa rồi đổi thường như phép kiểm tra round-trip không mất dữ liệu.
Ví dụ cũng cho thấy độ dài cần kiểm tra ở đúng giai đoạn. Nếu sản phẩm giới hạn chuỗi sau chuyển đổi, phải đo đầu ra theo đơn vị đã quy định. Chỉ mục trên chuỗi gốc có thể không còn trỏ tới cùng vị trí trong chuỗi đã chuyển đổi; một thuật toán highlight cần xử lý ánh xạ vị trí riêng.
2. Locale có thể thay đổi kết quả chữ thường
console.log('I'.toLowerCase()); // i
console.log('I'.toLocaleLowerCase('tr') === '\u0131'); // true
const dotted = '\u0130'; // İ
console.log(dotted.toLocaleLowerCase('en-US').length); // 2
console.log(dotted.toLocaleLowerCase('tr')); // i
Với quy tắc tiếng Thổ Nhĩ Kỳ, I đổi thành ı không có chấm. Với İ, kết quả en-US trong ví dụ có hai UTF-16 code unit, còn tr cho i. MDN toLocaleLowerCase mô tả phép chuyển đổi có xét locale.
Chọn locale từ yêu cầu của trường dữ liệu. Không nên để khóa bền vững thay đổi theo tùy chọn ngôn ngữ hiển thị của từng người dùng. Khi frontend và backend cùng tạo khóa tra cứu, cần thống nhất thuật toán, locale và tập dữ liệu kiểm thử thay vì chỉ thống nhất tên hàm.
3. Mã ASCII có thể dùng một contract hẹp hơn
function canonicalCode(value) {
if (typeof value !== 'string') {
throw new TypeError('code must be a string');
}
if (!/^[A-Za-z0-9-]{1,24}$/.test(value)) {
throw new RangeError('invalid ASCII code');
}
return value.toLowerCase();
}
console.log(canonicalCode('HT-Ab12')); // ht-ab12
console.log(canonicalCode('HT-Ab12') === canonicalCode('ht-ab12')); // true
Helper minh họa chỉ nhận 1–24 chữ cái Latin ASCII, chữ số hoặc dấu gạch nối rồi chuyển về chữ thường. Nó không trim, không tự chuyển số thành chuỗi và từ chối chữ ngoài ASCII trước khi chuyển đổi. Theo contract này, đầu ra có cùng độ dài vì mọi ký tự được chấp nhận đều ánh xạ một-một hoặc giữ nguyên.
Hai mã khác hoa thường chủ động trở thành cùng khóa; hệ thống phải kiểm tra trùng trên khóa đó thay vì âm thầm ghi đè bản ghi. Dấu gạch nối đứng một mình vẫn được regex chấp nhận, nên đây chưa phải toàn bộ định dạng mã của mọi doanh nghiệp. Tên người hoặc nội dung đa ngôn ngữ cần quy tắc khác.
4. Tách văn bản gốc khỏi khóa phục vụ tra cứu
Nếu có nhu cầu hiển thị nguyên bản, lưu giá trị gốc và tạo khóa theo chính sách riêng. Đổi hoa thường không thay cho chuẩn hóa Unicode, so sánh theo ngôn ngữ hoặc một thuật toán case folding đầy đủ. Quy tắc nào được chọn cũng cần nêu rõ trường hợp nhiều đầu vào cùng ra một khóa.
Khi thay chính sách đang được dùng, kiểm tra dữ liệu hiện hữu để tìm va chạm trước khi tái tạo khóa. Một thay đổi chỉ vài ký tự trong code vẫn có thể ảnh hưởng liên kết tra cứu và ràng buộc duy nhất nếu đầu ra thay đổi.
5. Checklist trước khi chuẩn hóa hoa thường
- Đây là văn bản hiển thị hay khóa tra cứu?
- Cần giữ lại nguyên bản để hiển thị hoặc đối chiếu không?
- Độ dài được đo trước hay sau chuyển đổi, theo đơn vị nào?
- Locale có được xác định rõ và thống nhất giữa các hệ thống?
- Nhiều đầu vào cùng ra một khóa sẽ bị từ chối hay xử lý thế nào?
Sáu khối mã Việt–Anh đã chạy bằng Node.js; kiểm tra thêm độ dài biên, sai kiểu và ký tự ngoài ASCII của helper. Chưa kiểm thử migration dữ liệu hoặc giao diện highlight thực tế.




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