Quy tắc so sánh trong lập trình năm 2024

Qua bài viết trước, bạn đã biết toán tử là gì, cũng như các loại toán tử trong JavaScript giúp cho việc tính toán. Tiếp theo, mình sẽ tìm hiểu về toán tử so sánh trong JavaScript.

Cụ thể, bài viết này tập trung vào tìm hiểu toán tử so sánh là gì, các loại toán tử so sánh trong JS, kết quả của phép so sánh và một số trường hợp đặc biệt (dễ nhầm lẫn) khi so sánh.

Toán tử so sánh là gì?

Toán tử so sánh là toán tử hai ngôi dùng để so sánh giá trị của hai toán hạng với nhau.

Các toán tử so sánh trong JavaScript bao gồm:

  • Toán tử so sánh lớn hơn

    console.log(5 > 6); // false (sai) console.log(5 < 6); // true (đúng) console.log(5 >= 6); // false (sai) console.log(5 <= 6); // true (đúng) console.log(5 == 6); // false (sai) console.log(5 === 6); // false (sai) console.log(5 != 6); // true (đúng) console.log(5 !== 6); // true (đúng)

    8 và toán tử so sánh nhỏ hơn

    console.log(5 > 6); // false (sai) console.log(5 < 6); // true (đúng) console.log(5 >= 6); // false (sai) console.log(5 <= 6); // true (đúng) console.log(5 == 6); // false (sai) console.log(5 === 6); // false (sai) console.log(5 != 6); // true (đúng) console.log(5 !== 6); // true (đúng)

    9.
  • Toán tử so sánh lớn hơn hoặc bằng

    let ret = 6 > 9; console.log(ret); // false (sai)

    0 và toán tử so sánh nhỏ hơn hoặc bằng

    let ret = 6 > 9; console.log(ret); // false (sai)

    1.
  • Toán tử so sánh bằng "không nghiêm ngặt"

    let ret = 6 > 9; console.log(ret); // false (sai)

    2 và toán tử so sánh bằng "nghiêm ngặt"

    let ret = 6 > 9; console.log(ret); // false (sai)

    3.
  • Toán tử so sánh khác "không nghiêm ngặt"

    let ret = 6 > 9; console.log(ret); // false (sai)

    4 và toán tử so sánh khác "nghiêm ngặt"

    let ret = 6 > 9; console.log(ret); // false (sai)

    5.

Ví dụ các phép toán so sánh:

let a = 1;
let b = 2;
a > b; // so sánh lớn hơn
a < b; // so sánh lớn hơn
a >= b; // so sánh lớn hơn hoặc bằng
a <= b; // so sánh nhỏ hơn hoặc bằng
a == b; // so sánh bằng không nghiêm ngặt
a === b; // so sánh bằng nghiêm ngặt
a != b; // so sánh khác không nghiêm ngặt
a !== b; // so sánh khác nghiêm ngặt

Kết quả của phép so sánh

Kết quả của phép so sánh luôn là một giá trị kiểu boolean.

  • let ret = 6 > 9; console.log(ret); // false (sai)

    6: đúng, chính xác
  • let ret = 6 > 9; console.log(ret); // false (sai)

    7: sai, không chính xác

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

Bạn có thể gán kết quả của phép so sánh cho một biến khác:

let ret = 6 > 9;
console.log(ret); // false (sai)

So sánh string trong javascript

Quy tắc so sánh hai string trong JavaScript cũng giống như hầu hết các ngôn ngữ lập trình khác. Đó là so sánh theo thứ tự "từ điển". Hay nói cách khác là so sánh từng chữ cái một (từ trái sang phải).

Ví dụ so sánh các string:

console.log("A" < "Z"); // true
console.log("Small" < "Smart"); // true
console.log("Big" < "BigBang"); // true

Tóm tắt thuật toán so sánh hai string như sau:

So sánh kí tự đầu tiên của hai string.

  • Nếu kí tự đầu tiên của string(1) lớn hơn (hoặc nhỏ hơn) kí tự đầu tiên của string(2) thì string(1) lớn hơn (hoặc nhỏ hơn) string(2). Suy ra, so sánh kết thúc.
  • Ngược lại, nếu hai kí tự đầu tiên bằng nhau thì tiếp tục so sánh đến các kí tự thứ hai.

Lặp lại việc so sánh như trên, cho đến khi so sánh kết thúc kết thúc hoặc đã so sánh hết các kí tự của ít nhất một string.

  • Nếu hai string có cùng độ dài thì chúng bằng nhau.
  • Ngược lại, string nào dài hơn thì string đó lớn hơn.

Trong ví dụ so sánh

let ret = 6 > 9;
console.log(ret); // false (sai)

8 kết quả là

let ret = 6 > 9;
console.log(ret); // false (sai)

6. Quá trình so sánh dừng lại ở bước một.

Trong ví dụ so sánh

console.log("A" < "Z"); // true
console.log("Small" < "Smart"); // true
console.log("Big" < "BigBang"); // true

0 kết quả là

let ret = 6 > 9;
console.log(ret); // false (sai)

6. Quá trình so sánh lặp lại nhiều lần.

  1. Kí tự đầu tiên

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    2 là giống nhau
  2. Kí tự thứ hai

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    3 cũng giống nhau
  3. Kí tự thứ ba

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    4 cũng giống nhau
  4. Kí tự thứ tư

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    5 nhỏ hơn

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    6. Suy ra, string

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    7 nhỏ hơn string

    console.log("A" < "Z"); // true console.log("Small" < "Smart"); // true console.log("Big" < "BigBang"); // true

    8.

Trong ví dụ so sánh

console.log("A" < "Z"); // true
console.log("Small" < "Smart"); // true
console.log("Big" < "BigBang"); // true

9 kết quả là

let ret = 6 > 9;
console.log(ret); // false (sai)

6. Quá trình so sánh cùng lặp lại nhiều lần. Ba kí tự đầu tiên là

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

1 đều giống nhau. Lúc này, string

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

1 kết thúc. Trong khi, string

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

3 còn thêm các kí tự

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

4 (độ dài string lớn hơn). Suy ra, string

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

1 nhỏ hơn string

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

3.

So sánh khác kiểu dữ liệu trong Javascript

Khi so sánh các toán hạng khác kiểu dữ liệu, JavaScript chuyển đổi giá trị các toán hạng ra dạng số, ví dụ:

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

Đối với kiểu dữ liệu boolean,

let ret = 6 > 9;
console.log(ret); // false (sai)

6 sẽ chuyển thành

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

8 và

let ret = 6 > 9;
console.log(ret); // false (sai)

7 chuyển thành

console.log(true == 1); // true
console.log(false == 0); // true

0.

console.log(true == 1); // true
console.log(false == 0); // true

Việc so sánh khác kiểu dữ liệu sử dụng toán tử bằng "không nghiêm ngặt"

let ret = 6 > 9;
console.log(ret); // false (sai)

2 dẫn đến một số trường hợp "phi logic", ví dụ:

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

Kì lạ phải không?

Nếu theo tính chất "bắc cầu" trong toán học thì nếu

console.log(true == 1); // true
console.log(false == 0); // true

2 là

let ret = 6 > 9;
console.log(ret); // false (sai)

6 và

console.log(true == 1); // true
console.log(false == 0); // true

4 là

let ret = 6 > 9;
console.log(ret); // false (sai)

6, suy ra

console.log(true == 1); // true
console.log(false == 0); // true

6 cũng phải là

let ret = 6 > 9;
console.log(ret); // false (sai)

6 (vì cùng bằng

console.log(true == 1); // true
console.log(false == 0); // true

0).

Nhưng thực tế lại không phải như vậy, hai phép so sánh đầu tiên là so sánh khác kiểu dữ liệu, nên

console.log(true == 1); // true
console.log(false == 0); // true

9 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

0 đều được chuyển thành dạng số và bằng 0.

Trong khi phép so sánh thứ ba là so sánh cùng kiểu dữ liệu, nên không có quá trình chuyển đổi dữ liệu xảy ra. Dẫn đến, kết quả của phép so sánh cuối là

let ret = 6 > 9;
console.log(ret); // false (sai)

7.

Để giải quyết vấn đế này, JavaScript tạo ra toán tử so sánh bằng "nghiêm ngặt"

let ret = 6 > 9;
console.log(ret); // false (sai)

3.

So sánh bằng nghiêm ngặt

Đối với toán tử so sánh bằng "nghiêm ngặt", JavaScript sẽ không thực hiện chuyển đổi kiểu dữ liệu.

Nói cách khác, hai giá trị khác kiểu dữ liệu thì luôn khác nhau, ví dụ:

// So sánh bằng không nghiêm ngặt
console.log("" == 0); // true
// So sánh bằng nghiêm ngặt
console.log("" === 0); // false

Tương tự với so sánh bằng nghiêm ngặt, JavaScript cũng có so sánh khác nghiêm ngặt, ví dụ:

// So sánh khác không nghiêm ngặt
console.log("" != 0); // false
// So sánh khác nghiêm ngặt
console.log("" !== 0); // true

So sánh với

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4

Khác với các kiểu dữ liệu khác, việc so sánh

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 thường không rõ ràng cho lắm.

Khi sử dụng toán tử so sánh bằng "nghiêm ngặt"

let ret = 6 > 9;
console.log(ret); // false (sai)

3 thì dĩ nhiên là hai giá trị này khác nhau. Vì chúng khác kiểu dữ liệu.

console.log(null === undefined); // false

Nhưng khi sử dụng toán tử so sánh bằng "không nghiêm ngặt"

let ret = 6 > 9;
console.log(ret); // false (sai)

2 thì kết quả lại là

let ret = 6 > 9;
console.log(ret); // false (sai)

6.

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

0

Thực tế, JavaScript đã quy định

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 là bằng nhau (với trường hợp

let ret = 6 > 9;
console.log(ret); // false (sai)

2). Và chúng không bằng (

let ret = 6 > 9;
console.log(ret); // false (sai)

  1. các giá trị khác.

Khi sử dụng các toán tử so sánh

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

8,

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

9,

let ret = 6 > 9;
console.log(ret); // false (sai)

0 và

let ret = 6 > 9;
console.log(ret); // false (sai)

1 thì sao?

Hai giá trị này sẽ được chuyển sang dạng số. Cụ thể

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 chuyển thành

console.log(true == 1); // true
console.log(false == 0); // true

0 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 chuyển thành

// So sánh khác không nghiêm ngặt
console.log("" != 0); // false
// So sánh khác nghiêm ngặt
console.log("" !== 0); // true

1.

Khi sử dụng các toán tử so sánh

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

8,

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

9,

let ret = 6 > 9;
console.log(ret); // false (sai)

0 và

let ret = 6 > 9;
console.log(ret); // false (sai)

1 với

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 và

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 thì kết quả đều

let ret = 6 > 9;
console.log(ret); // false (sai)

7 hết.

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

1

Bây giờ, mình thử so sánh hai giá trị này với số

console.log(true == 1); // true
console.log(false == 0); // true

0 xem có gì kỳ lạ không nào!

So sánh

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 với 0

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

2

Trong các phép so sánh (1), (2),

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 chuyển thành số

console.log(true == 1); // true
console.log(false == 0); // true

0 nên ta có đáp án lần lượt là

let ret = 6 > 9;
console.log(ret); // false (sai)

7 và

let ret = 6 > 9;
console.log(ret); // false (sai)

6. Nhưng ở phép so sánh (3),

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 không chuyển thành

console.log(true == 1); // true
console.log(false == 0); // true

0 nên kết quả là

let ret = 6 > 9;
console.log(ret); // false (sai)

7.

Đây lại là một điều khá "phi logic". Vì theo kết quả trên thì

console.log("" == 0); // true console.log("0" == 0); // true console.log("" == "0"); // false

3 lớn hơn hoặc bằng 0 (sử dụng

let ret = 6 > 9; console.log(ret); // false (sai)

0), nhưng lại không bằng 0 (sử dụng

let ret = 6 > 9; console.log(ret); // false (sai)

2).

So sánh

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 với 0

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

3

Kết quả là

let ret = 6 > 9;
console.log(ret); // false (sai)

7 hết.

Trong các phép so sánh (1) và (2),

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 chuyển thành

// So sánh khác không nghiêm ngặt
console.log("" != 0); // false
// So sánh khác nghiêm ngặt
console.log("" !== 0); // true

1 nên chắc chắn khác

console.log(true == 1); // true
console.log(false == 0); // true

0. Trong khi phép so sánh (3),

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 không bằng (

let ret = 6 > 9;
console.log(ret); // false (sai)

console.log(true == 1); // true
console.log(false == 0); // true

0. Vì như mình đã nói ở trên,

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

4 chỉ bằng (

let ret = 6 > 9;
console.log(ret); // false (sai)

console.log("" == 0); // true
console.log("0" == 0); // true
console.log("" == "0"); // false

3 mà thôi.

Thứ tự ưu tiên của các toán tử so sánh

Các toán tử so sánh có thứ tự ưu tiên giống nhau. Khi trong biểu thức có nhiều toán tử so sánh, thứ tự thực hiện là từ trái sang phải.

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

4

Thoạt đầu nhìn qua, bạn sẽ thấy kết quả trên là vô lý phải không?

Vì theo toán học thì chắc chắn số

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

12 lớn hơn số

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

13 và số

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

13 lớn hơn số

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

8, nên kết quả (2) phải bằng

let ret = 6 > 9;
console.log(ret); // false (sai)

6 mới hợp lý.

Nhưng nếu bạn áp dụng đúng quy tắc thứ tự ưu tiên vào đây, bạn sẽ thấy kết quả trên là hoàn toàn đúng.

Vì JavaScript sẽ thực hiện so sánh hai số đầu tiên trước,

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

17 là đúng nên kết quả của phép so sánh này là

let ret = 6 > 9;
console.log(ret); // false (sai)

6. Khi đó, mình có thể viết lại như sau:

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

5

Rõ ràng, đây là phép so sánh hai kiểu dữ liệu khác nhau. Vì vậy,

let ret = 6 > 9;
console.log(ret); // false (sai)

6 được chuyển thành dạng số và bằng

console.log("5" > 4); // true, vì "5" chuyển thành 5
console.log("01" == 1); // true, vì "01" chuyển thành 1
console.log("11" == 1); // false, vì "11" chuyển thành 11

8. Mà

console.log(5 > 6); // false (sai)
console.log(5 < 6); // true (đúng)
console.log(5 >= 6); // false (sai)
console.log(5 <= 6); // true (đúng)
console.log(5 == 6); // false (sai)
console.log(5 === 6); // false (sai)
console.log(5 != 6); // true (đúng)
console.log(5 !== 6); // true (đúng)

21 là

let ret = 6 > 9;
console.log(ret); // false (sai)

7.