Javascript - Những khó hiểu trong câu lệnh điều kiện if và phép toán so sánh (p2)
Ở phần trước, tôi đã tổng kết lại một số nguyên tắc của câu lệnh điều kiện if, phép so sánh == và ===. Chúng ta hãy cùng bắt đầu phần 2 với điều khó hiểu mà tôi nêu ra ở cuối bài trước: 0 > null; // false 0 == null; //false 0 === null; // false 0 < null; // vẫn false Tuy nhiên 0 ...
Ở phần trước, tôi đã tổng kết lại một số nguyên tắc của câu lệnh điều kiện if, phép so sánh == và ===. Chúng ta hãy cùng bắt đầu phần 2 với điều khó hiểu mà tôi nêu ra ở cuối bài trước:
0 > null; // false 0 == null; //false 0 === null; // false 0 < null; // vẫn false
Tuy nhiên
0 >= null; // true 0 <= null; // true (@@)
Một vấn đề nữa, khi tôi suy nghĩ theo cách thông thường:
1 > 'x' // false
Như vậy thì rõ ràng 1 <= 'x' sẽ là true rồi.
Tuy nhiên, khi thử biểu thức trên, kết quả lại không giống với cách nghĩ thông thường lắm. (T_T)
Về cơ bản thì cả 4 phép toán so sánh >, >=, <, <= sẽ tuân theo quy luật sau:
- Trường hợp cả 2 vế cùng kiểu Number hoặc String
- Nếu cả 2 vế là kiểu Number, so sánh giá trị của 2 số
- Nếu cả 2 vế là kiểu String, so sánh theo Unicode Code Point
- Trường hợp 2 vế khác kiểu
- Một vế là giá trị kiểu Number, một vế là giá trị có thể chuyển được về kiểu Number, chuyển về Number và so sánh giá trị
- Nếu 1 trong 2 vế là NaN, false
- Một vế là giá trị kiểu String, một vế là giá trị có thể chuyển được về kiểu String, chuyển về kiểu String và so sánh theo Unicode Code Point
- Nếu một trong 2 vế không thể chuyển được về kiểu Number hoặc String, hoặc khi chuyển kiểu bị trở thành giá trị NaN, false
- Nếu một vế là giá trị kiểu Number, một vế là giá trị kiểu String, giá trị kiểu String sẽ được chuyển về kiểu Number và so sánh giá trị '100' > '99' // sẽ cho kết quả false, vì Code Point của '9' > Code Point của '1' '100' > 99 // sẽ cho kết quả true, vì '100' sẽ được chuyển về kiểu số thành 100 > 99
⚠ Chú ý: chỗ này dễ xảy ra BUG
Như vấn đề thứ hai tôi đã nêu ra ở phần mở đầu. Với đa số ngôn ngữ lập trình, cũng như theo cách nghĩ thông thường, nếu 2 vế của biểu thức > cho giá trị là false, vậy thì biểu thức ngược lại <= sẽ cho giá trị là true. Tuy nhiên do việc chuyển kiểu khi so sánh của javascript mà cho dù 2 vế của biểu thức cùng giá trị, 2 phép toán > và <= sẽ đều cho giá trị false. Như các ví dụ dưới đây.
1 > 'x' // false 1 <= 'x' // false
Nguyên do là khi chuyển 'x' (kiểu String) sang kiểu Number: (Number('x')), giá trị 'x' bị trở thành NaN. undefined cũng tương tự như vậy:
undefined > 0 // false undefined <= 0 // false undefined > undefined // false
Một số ví dụ
// so sánh kiểu Boolean true > false // kết quả là true, vì khi chuyển sang kiểu Number, 1 > 0 true > 0 // kết quả là true // so sánh với giá trị null null < 1 // true, vì null khi chuyển sang kiểu Number có giá trị 0, 0 < 1 null > 1 // false, 0 > 1 // so sánh kiểu object var obj = {}; obj > 0; // false, vì obj khi chuyển sang kiểu Number là NaN, NaN > 0 obj <= 0; // false, NaN <= 0 // function obj.valueOf = function() { return 1; } obj > 0; // true, bởi obj giờ đã có thể chuyển sang kiểu Number, 1 > 0
Như vậy tôi đã kết thúc loạt bài về câu lệnh if và các phép toán so sánh trong ngôn ngữ javascript (:phew). Quả thật javascript không hề đơn giản nhưng cũng khá thú vị. Hi vọng bài viết có ích cho các lập trình viên javascript tránh được các bug mò mãi không ra :D