Hướng dẫn so sánh javascript

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 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 > < >= = 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à

Chủ Đề