Có những phép so sánh mà chúng ta biết từ toán học:

  • Lớn hơn/Nhỏ hơn: a > ba < b.
  • Lớn hơn hoặc bằng/Nhỏ hơn hoặc bằng: a >= b, a <= b.
  • Kiểm tra bằng nhau: a === b (chú ý rằng khi để dấu "==" hay một dấu như a = b có nghĩa là một phép gán).
  • Không bằng nhau. Trong Javascript, phép so sánh đó được viết là a != b.

Boolean là ​kết quả

Học Java cơ bản nâng cao cấp tốc 

Tương tự như các phép tính khác, phép so sánh được trả về là một giá trị. Giá trị đó trả về là dạng boolean.

  • true - nghĩa là "có", "đúng" hay "nói thật".
  • false - nghĩa là "không" , "sai" hay "nói dối".
alert( 2 > 1 );  // true (correct)
alert( 2 == 1 ); // false (wrong)
alert( 2 != 1 ); // true (correct)

 

Một kết quả so sánh có thể gán vào một biến như bất kì giá trị nào:

let result = 5 > 4; // assign the result of the comparison
alert( result ); // true

So sánh chuỗi

Để xem chuỗi nào lớn hơn chuỗi kia, thứ tự "từ điển" được sử dụng để so sánh.

Nói cách khác, các chuỗi được so sánh với nhau theo từng chữ cái.

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

Thuật toán so sánh 2 chuỗi rất đơn giản: 

  1. So sánh những kí tự đầu tiên của 2 chuỗi.
  2. Nếu kí tự của chuỗi đầu lớn hơn (hay nhỏ hơn) chuỗi sau, ta sẽ tính luôn chuỗi đầu lớn hơn (hay nhỏ hơn) chuỗi sau.
  3. Nếu kí tự đầu của 2 chuỗi bằng nhau, ta sẽ so sánh kí tự thứ hai của hai chuỗi tương tự như trước.
  4. Lặp lại cho tới khi kết thúc chuỗi bất kì.
  5. Nếu cả hai chuỗi kết thúc cùng lúc thì cả hai chuỗi bằng nhau. Còn không chuỗi dài hơn sẽ lớn hơn.

Ở ví dụ trên, phép so sánh 'Z' > 'A' ra kết quả là true

Chuỗi 'Glow' và 'Glee' được so sánh theo từng kí tự:

  1. G bằng G
  2. bằng l
  3. o lớn hơn e. Chúng ta dừng từ đó. Ta thấy rằng chuỗi đầu lớn hơn chuỗi sau.

Phép so sánh ở trên tương đương với phép toán sử dụng trong cuốn từ điển hay cuốn danh bạ. Nhưng không hẳn là hoàn toàn giống nhau.

Ví dụ, viết hoa và viết thường rất quan trọng. Chữ hoa "A" không bằng với chữ thường "a". Chữ nào lớn hơn? Thực tế là chữ thường "a". Tại sao lại như vậy? Bởi ký tự chữ thường có số lớn hơn trong bảng mã Unicode.

So sánh những giá trị có dạng dữ liệu khác nhau

Khi so sánh những giá trị có dạng dữ liệu khác nhau, những giá trị đó được chuyển đổi thành số.

alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1

Với giá trị booleantrue chuyển về là 1 và false chuyển về là 0.

alert( true == 1 ); // true
alert( false == 0 ); // true

Trong một vài trường hợp:

  • Hai giá trị là bằng nhau.
  • Một trong hai giá trị đó là true và giá trị còn lại là false.
let a = 0;
alert( Boolean(a) ); // false

let b = "0";
alert( Boolean(b) ); // true

alert(a == b); // true!

Trong Javascript, trường hợp này là khá bình thường. Việc kiểm tra bằng nhau thường bằng cách sử dụng chuyển đổi số (từ đó mà "0" chuyển thành 0), việc chuyển đổi Boolean thường sử dụng quy tắc khác.

Kiểm tra bằng nhau nghiêm ngặt

Việc kiểm tra bằng nhau sử dụng "==" thường có vấn đề. Phép kiểm tra này thường không phân biệt được sự khác nhau giữa 0 và false:

alert( 0 == false ); // true

Trường hợp này tương tự với chuỗi rỗng:

alert( '' == false ); // true

Đây là bởi toán hạng của các dạng dữ liệu khác nhau được chuyển về là số. Từ đó, một chuỗi rỗng, tương tự như false, chuyển về 0.

Vậy chúng ta cần làm gì để phân biệt được 0 với false?

Phương pháp kiểm tra bằng nhau nghiêm ngặt "===" sẽ giúp chúng ta kiểm tra bằng nhau mà không làm chuyển đổi kiểu dữ liệu.

Nói cách khác, nếu a và b là 2 dạng dữ liệu khác nhau, thì việc sử dụng phép so sánh a === b sẽ lập tức chuyển về false khi mà dạng dữ liệu không được chuyển đổi.

alert( 0 === false ); // false, because the types are different

Cũng có một phép so sánh gọi là "kiểm tra bằng nhau không nghiêm ngặt" bằng cách sử dụng "!==" tương tự như "!=".

So sánh với null và undefined

Có một vài trường hợp khi null hoặc undefined được so sánh với những giá trị khác.

Với việc kiểm tra bằng nhau nghiêm ngặt ===

Những giá trị này là khác nhau bởi mỗi giá trị này thuộc kiểu dữ liệu khác nhau.

alert( null === undefined ); // false

Với việc kiểm tra không nghiêm​ ngặt ==

Đây là quy tắc đặc biệt. Hai giá trị null và undefined bằng nhau nhưng không bằng những giá trị khác.

alert( null == undefined ); // true

Với việc so sánh thông thường < > <= >=

Giá trị null/undefined được chuyển về giá trị số: null chuyển thành 0undefined chuyển về NaN.

Kết quả lạ giữa null và 0

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

Ở kết quả cuối trong ví dụ trên ta thấy null lớn hơn hoặc bằng 0. Vậy nghĩa là một trong hai phép so sánh kia là đúng, nhưng cả hai đều sai.

Nguyên nhân là do việc kiểm tra bằng nhau == và phép so sánh thông thường > < >= <= hoạt động khác nhau. Việc so sánh chuyển giá trị null về số và trở thành 0. Vì thế ở trường hợp null >= 0 là true mà null > 0 là false.

Mặt khác, việc kiểm tra bằng nhau == cho undefined và null lại không chuyển đổi giá trị. Vì thế 2 giá trị này bằng nhau nhưng không bằng những giá trị nào khác. Từ đó vì sao null == 0 trả về là false.

Undefined không thể so sánh được

Giá trị undefined không nên sử dụng vào so sánh:

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

Tại sao undefined lại luôn trả về giá trị false?

  • Trường hợp undefined > 0 và undefined < 0 chuyển về false bởi undefined chuyển về giá trị NaN. Và NaN là giá trị số đặc biệt luôn chuyển giá trị về false trong bất kì phép so sánh nào.
  • Việc kiểm tra bằng nhau undefined == 0 chuyển giá trị về false bởi undefined chỉ có thể bằng null và không thể bằng giá trị nào khác được.

Tránh gặp vấn đề

Tại sao chúng ta phải xem những ví dụ này? Chúng ta có cần phải nhớ những thứ này bất cứ lúc nào không? Thực tế, những vấn đề phức tạp này sẽ dần trở nên quen thuộc theo thời gian. Tuy nhiên, có một cách chắc chắn để tránh được mọi vấn đề này.

Hãy coi bất cứ so sánh nào với undefined/null một cách đặc biệt, trừ trường hợp so sánh nghiêm ngặt ===.

Không sử dụng phép so sánh > < >= <= với biến undefined/null trừ khi chúng ta chắc chắn biết mình đang làm gì. Nếu một biến có các giá trị này, hãy kiểm tra biến đó một cách riêng biệt.

Tóm tắt

  • Các phép so sánh trả về một giá trị logic.
  • Các chuỗi được so sánh qua từng kí tự theo thứ tự trên từ điển.
  • Khi có so sánh giá trị giữa các loại dữ liệu khác nhau, những giá trị đó được chuyển về số (trừ khi phép so sánh đó là kiểm tra bằng nhau nghiêm ngặt)
  • Giá trị null và undefined bằng nhau khi sử dụng "==" và không bằng những giá trị khác
  • Cẩn thận khi sử dụng so sánh > và < với các biến chứa giá trị null/undefined. Nên kiểm tra riêng biệt giá trị null/undefined hơn.