11/08/2018, 19:52

Javascript - Những khó hiểu trong câu lệnh điều kiện if và phép toán so sánh

Theo cá nhân tôi, Javascript có lẽ là một trong những ngôn ngữ dễ học, dễ viết nhất. Một web developer mới bắt đầu có lẽ chỉ cần từ 1 đến 2 tuần để có thể học và viết được Javascript. Tuy nhiên, Javascript cũng tồn tại những điều không đơn giản. Bạn hãy thử suy nghĩ và trả lời vài câu hỏi dưới đây ...

Theo cá nhân tôi, Javascript có lẽ là một trong những ngôn ngữ dễ học, dễ viết nhất. Một web developer mới bắt đầu có lẽ chỉ cần từ 1 đến 2 tuần để có thể học và viết được Javascript. Tuy nhiên, Javascript cũng tồn tại những điều không đơn giản.
Bạn hãy thử suy nghĩ và trả lời vài câu hỏi dưới đây (tất nhiên là đừng gõ console hay tương tự vậy nhé). Hãy trả lời kết quả của từng dòng lệnh dưới đây

  • Phần 1:

    1 == String(1);
    new String(1) == new String(1);
    new String(1) === new String(1);
    

    Đơn giản đúng không? Chúng ta cùng tiếp tục nhé:

  • Phần 2:

    0 == [];
    0 == false;
    [] == false;
    

    Hãy kiểm tra kết quả bằng console và cùng chạy đoạn lệnh sau nhé:

    if (0) 
    console.log("0 là true"); 
    else 
    console.log("0 là false");
    

    if ([]) 
    console.log("[] là true"); 
    else 
    console.log("[] là false");
    

    So sánh 2 đoạn lệnh bạn vừa chạy với kết quả ở phần 2, khó hiểu vãi đúng không. T_T.

  • Phần 3:

    0 == undefined; // kết quả là false
    0 == !!undefined; // cái này kết quả cũng là false chứ còn gì nữa
    

    Tuy nhiên, khi bạn kiểm tra lại bằng console, đây là điều khó hiểu tiếp theo. (:rofl)

Trong Javascript, một function có thể thay đổi giá trị và cả kiểu của các biến global, đi kèm với những điều khó hiểu trên, một chương trình viết bằng Javascript sẽ rất dễ xuất hiện bug. Xin được tổng kết lại một số quy tắc sử dụng if và các phép toán so sánh:

Để bắt đầu, ta hãy cùng xem lại các kiểu dữ liệu của biến số trong Javascript.

  • Primitive Data Type
Kiểu Phân loại Độ lớn
String giá trị kiểu xâu bắt đầu từ chuỗi ' trở lên
Number kiểu số 64 bit
Boolean kiểu logic true/false
Null giá trị rỗng null
Undefined chưa định nghĩa giá trị undefined
  • Reference Data Type: là kiểu dữ liệu tham chiếu tới một object

Trong javascript không có sự phân biệt giữa kiểu số nguyên và số thực

  • Giá trị false nằm trong các trường hợp sau

    • '
    • 0
    • NaN
    • null
    • undefined
  • Giá trị true ngoài 5 trường hợp trên

Vì thế if ([]) là true còn if (0) là false nhé. Mặc dù 0 == [] là true

Nhiều người (trong đó có cả tôi) vẫn hiểu đơn giản rằng phép toán === hoặc !== ngoài so sánh giá trị thì còn so sánh kiểu của dữ liệu. Điều này đúng với cả giá trị null và undefined. Tuy nhiên với những trường hợp dưới đây sẽ không đúng:

NaN === NaN // giá trị của biểu thức này là false
new String(1) === new String(1) // mặc dù cùng là kiểu object String, có giá trị 1, tuy nhiên biểu thức này cũng cho kết quả là false

Trên thực tế, phép toán so sánh === tuân theo quy luật dưới đây:

  1. Nếu x và y khác kiểu nhau, false
  2. Nếu như cả 2 vế đều là null hoặc undefined (null === null), true (tuy nhiên điều này không đúng với NaN đâu nhé :-p)
  3. Nếu cả 2 vế đều là kiểu Number, 1 trong 2 vế, hoặc cả 2 vế là NaN, false. Còn không thì so sánh giá trị
  4. Nếu cả 2 vế đều là kiểu String, nội dung giống nhau: true, còn lại false
  5. Nếu cả 2 vế đều là kiểu Boolean, giống nhau thì là true, khác nhau là false
  6. Nếu cả 2 vế đều là kiểu Object tham chiếu, nếu cùng tham chiếu tới 1 object: true, còn lại là false

Phép so sánh == (hoặc !=) cũng không chỉ đơn thuần chỉ so sánh giá trị của dữ liệu mà tuân theo quy luật dưới đây:

  • Nếu x và y có cùng kiểu dữ liệu, thì phép toán === (hoặc !==) sẽ được áp dụng
  • Nếu x và y khác kiểu dữ liệu, kết quả sẽ tuân theo:
  1. Nếu cả 2 vế đều là null, hoặc undefined, true
  2. Nếu một vế là giá trị kiểu Number, vế còn lại là giá trị kiểu String, String sẽ được convert sang kiểu Number và so sánh giá trị
  3. Nếu một vế là kiểu Boolean, một vế là kiểu Number, Boolean sẽ được chuyển sang kiểu Number và so sánh giá trị
  4. Nếu một vế là kiểu Boolean, một vế là kiểu String, cả 2 vế sẽ được chuyển về kiểu Number và so sánh giá trị
  5. Nếu một vế là kiểu Number, một vế là kiểu Object tham chiếu, vế Object tham chiếu sẽ được chuyển sang Number và so sánh giá trị
  6. Nếu một vế là kiểu String, một vế là kiểu Object tham chiếu, vế Object tham chiếu sẽ được chuyển sang kiểu String và so sánh nội dung
  7. Ngoài những trường hợp trên, tất cả đều là false

Một chút lưu ý là phép toán chuyển sang kiểu Number trong javascript không phải là hàm parse... (parseInt hay parseFloat) đâu nhé, mà là hàm Number(). Như đoạn lệnh dưới đây:

0 == '0a'; // kết quả là false
0 == parseInt('0a'); // kết quả là true

Bạn hãy tự kiểm tra lại với lệnh 0 == Number('0a')

Trong phần này tôi đã tổng kết lại những quy tắc của câu lệnh điều kiện if, và các phép toán so sánh ===, ==. Phần tiếp tôi sẽ tổng hợp các quy tắc với các phép so sánh >, >=, <, <= để cùng đả thông sự khó hiểu dưới đây:

0 > null; // false
0 == null; //false
0 === null; // false
0 < null; // vẫn false

Tuy nhiên

0 >= null; // true
0 <= null; // true (@@)

Mời các bạn tham khảo phần 2.

0