So sánh gần bằng javascript

Hôm nay tôi xin giới thiệu với các bạn một chuyên mục mới, chuyên mục này được gọi là Chuyện xưa cũ, đây sẽ là nơi tôi chia sẻ với các bạn những câu chuyện mà có thể các bạn đã từng biết, và đã từng quên, nói chung đây sẽ là những thứ xưa như trái đất, cứ ngỡ ai cũng biết nhưng thực tế chẳng phải vậy. Đâu đó sẽ giống với chuyên mục Java những điều có thể bạn đã biết trước đây, nhưng lần này những câu chuyện tôi kể sẽ rộng hơn, không chỉ đơn giản là về kỹ thuật nữa. Hy vọng các bạn sẽ thích thú với chủ đề này.

Nào cùng bắt đầu với câu chuyện đầu tiên.

Bạn đã biết sự khác biệt của hai toán tử so sánh bằng === và == trong Javascript. Bạn thấy cả hai đều được sử dụng nhưng bạn không chắc về việc bản thân nên sử dụng cái nào. Bạn muốn tìm ra một lý do để thuyết phục bản thân. Vâng bài viết này là dành cho bạn.

So sánh bằng và cùng loại với ===

x === y

Toán tử === chỉ trả về true nếu như cả hai toán hạng đều cùng một loại và có cùng giá trị. Nếu so sánh khác loại, kết quả sẽ trả về false.

Với định nghĩa như thế, hầu hết các trường hợp sẽ được giải quyết, chẳng hạn như chuỗi "0" và 0 khi so sánh kết quả sẽ là false.

Cá nhân tôi khuyên các bạn hãy nên sử dụng === khi lập trình với Javascript, và hãy bỏ qua hoàn toàn toán tử ==.

Cái quái gì diễn ra khi sử dụng ==?

x == y

Toán tử == sẽ cố gắng chuyển đổi kiểu của toán hạng nếu như hai toán hạng có kiểu khác nhau, và chỉ bắt đầu so sánh sự bằng nhau khi đã thực hiện đổi kiểu xong. Nếu kiểu khác nhau, một trong hai, hoặc cả hai toán hạng sẽ được chuyển về một kiểu chung, hay còn gọi là kiểu trung gian. Sự chuyển đổi này thì thật sự rất là phức tạp, để có một cái nhìn chi tiết hơn các bạn có thể xem chi tiết trên MDN hay ECMAScript specification.

Và vì lý do trên, khi bạn so sánh chuỗi "0" và số 0, thì toán hạng đầu tiên sẽ được chuyển đổi thành kiểu số, và thực hiện so sánh, kết quả sẽ trả về true.

"0" == 0

=> ToNumber["0"] === 0

So sánh chuỗi và số thì còn có thể dễ hiểu, nhưng còn có những quy định phức tạp khác dẫn đến những kết quả cực kì vô lý, làm cho nhiều ngưỡi dễ phát khùng khi sử dụng Javascript như thanh niên Tôi đi code dạo đã từng. Ví dụ như khi so sánh null, undefined và false.

false == undefined // false

false == null // false

null == undefined // true

Giờ thì bạn đã biết, chỉ sử dụng === thôi nhé!

Tóm lại, khi so sánh bằng trong Javascript hãy sử dụng toán tử ===. Với toán tử này, khi bạn so sánh khác loại, kết quả sẽ luôn trả về false. Bạn sẽ nhận được kết quả đúng như mong đợi, mà không phải vắt óc suy nghĩ tại sao, hay cố gắng nhớ hết những quy tắc chuyển đổi.

Lưu ý rằng, toán tử so sánh là để dùng với những kiểu dữ liệu nguyên bản [primitive type]. Để so sánh bằng giữa các đối tượng [object] hay mảng [array] thì chúng ta phải sử dụng cách tiếp cận khác.

Hy vọng qua bài viết ngắn gọn này các bạn đã tìm được chân lý của đời mình về việc sử dụng == hay ===. Mọi ý kiến đóng góp, đừng ngại mà hãy kéo xuống khung comment bên dưới nhé. Hẹn gặp lại các bạn trong các bài viết tiếp theo.

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:

Kiểu của biến trong Javascript

Để 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.

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

Câu lệnh if trong Javascript

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

  • 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

Phép so sánh === [!==]

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 == [!=]

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']

Tổng kết

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 >, >=, = null; // true 0

Chủ Đề