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. Phần 1: Đơn giản đúng không? Chúng ta cùng tiếp tục nhé: Phần 2: Hãy kiểm tra kết quả bằng console và cùng chạy đoạn lệnh sau nhé: và 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: 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ạ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
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.
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à falseTrên thực tế, phép toán so sánh === tuân theo quy luật dưới đây:
- Nếu x và y khác kiểu nhau, false
- 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]
- 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ị
- Nếu cả 2 vế đều là kiểu String, nội dung giống nhau: true, còn lại false
- Nếu cả 2 vế đều là kiểu Boolean, giống nhau thì là true, khác nhau là false
- 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:
- Nếu cả 2 vế đều là null, hoặc undefined, true
- 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ị
- 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ị
- 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ị
- 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ị
- 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
- 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à trueBạ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