JavaScript là một ngôn ngữ lập trình cực kỳ linh hoạt, nhưng cũng đầy những điều bí ẩn khiến nhiều lập trình viên bối rối. Nếu bạn đã từng làm việc với JS, chắc chắn bạn đã gặp những hình thức so sánh kỳ quái như 0 == "0" hay tự hỏi tại sao 0.1 + 0.2 !== 0.3. Trong bài viết này, chúng ta sẽ cùng tìm hiểu 15 hiện tượng thú vị và khó hiểu của JavaScript để bạn có thể hiểu rõ hơn về cách mà ngôn ngữ này hoạt động và tránh những cạm bẫy có thể xảy ra trong mã của mình. Hãy sẵn sàng để khám phá nào!
1. So Sánh "False" == 0 Không Như Bạn Nghĩ
Bạn có thể nghĩ rằng "False" bằng với 0, nhưng thực tế là: "False" == 0 trả về true, còn "False" == "0" lại trả về false. Điều này xảy ra do JavaScript thực hiện ép kiểu trong các phép so sánh. Khi so sánh một chuỗi với một số, JS sẽ chuyển đổi chuỗi thành số, dẫn đến tình trạng không như mong đợi.
javascript
console.log("False" == 0); // true
console.log("False" == "0"); // false
2. Sự Sai Khác Biệt Giữa 0.1 + 0.2 và 0.3
Một ví dụ kinh điển trong JavaScript là:
javascript
console.log(0.1 + 0.2 === 0.3); // false
JavaScript sử dụng chuẩn IEEE-754 cho số học dấu phẩy động, điều này có thể dẫn đến kết quả không chính xác. Đối với các phép so sánh như vậy, hãy sử dụng một tỷ lệ sai số nhỏ để tránh lỗi.
javascript
const isEqual = Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON;
console.log(isEqual); // true
3. Cú Pháp Kỳ Lạ Của typeof null
Khi bạn kiểm tra kiểu của null, nó lại trả về "object".
javascript
console.log(typeof null); // object
Điều này là một sai lầm lịch sử trong JavaScript, khiến việc thay đổi kiểu của null trở thành một vấn đề lớn cho các mã hiện có.
4. Phép Cộng Hai Mảng
Khi bạn cộng hai mảng lại với nhau, kết quả thật bất ngờ:
javascript
console.log([1, 2, 3] + [4, 5, 6]); // "1,2,34,5,6"
JavaScript chuyển đổi các mảng thành chuỗi và thực hiện phép nối chuỗi.
5. NaN Không Bao Giờ Bằng Chính Nó
Một giá trị đặc biệt NaN (Not a Number) không thể bằng chính nó:
javascript
console.log(NaN === NaN); // false
Để kiểm tra NaN, hãy sử dụng Number.isNaN():
javascript
console.log(Number.isNaN(NaN)); // true
6. Một Số Phép So Sánh Thú Vị Giữa Mảng
Phép so sánh như: [] == ![] sẽ trả về true, nhưng [] == [] lại là false. Điều này xảy ra do cách mà JavaScript xử lý tham chiếu và kiểu dữ liệu.
7. Giá Trị Trả Về Khi Không Có Tham Số
Sử dụng Math.max() mà không có tham số sẽ trả về -Infinity:
javascript
console.log(Math.max()); // -Infinity
8. Các Trường Hợp Đặc Biệt Về Toán Tử So Sánh
Một số ví dụ gây nhầm lẫn:
javascript
console.log(0 == "0"); // true
console.log(0 == []); // true
console.log("0" == []); // false
9. Tương Tác Với null và undefined
Khi bạn cộng null với 1, bạn sẽ nhận được 1, trong khi undefined cộng với 1 sẽ trả về NaN:
javascript
console.log(undefined + 1); // NaN
console.log(null + 1); // 1
10. Khác Biệt Giữa new Array(3) và [,,]
Sự khác biệt là new Array(3) tạo một mảng rỗng với 3 vị trí, còn [,,] tạo một mảng với hai giá trị undefined:
javascript
console.log(new Array(3)); // [ <3 empty items> ]
console.log([,,]); // [undefined, undefined]
11. Phân Tích Cú Pháp Đặc Biệt
Hàm parseFloat và parseInt hoạt động khác nhau khi gặp chuỗi có cả số và chữ:
javascript
console.log(parseFloat("3.14abc")); // 3.14
console.log(parseInt("3.14abc")); // 3
12. Độ Ưu Tiên Phép Toán
Thứ tự thực hiện các phép toán có thể ảnh hưởng đến kết quả:
javascript
console.log([] + {}); // "[object Object]"
console.log({} + []); // "[object Object]"
13. Lỗi Chính Xác Trong Tính Toán
Khi thực hiện 0.1 * 0.1, bạn có thể thấy điều này:
javascript
console.log(0.1 * 0.1); // 0.010000000000000002
Điều này là do lỗi chính xác dấu phẩy động nhị phân.
14. Giá Trị Truthy và Falsy
Trong JavaScript, có một số giá trị được xem là falsy, bao gồm: "", 0, null, undefined, NaN và false. Ngược lại, bất cứ giá trị nào khác đều là truthy:
javascript
console.log(!!""); // false
console.log(!!0); // false
console.log(!!null); // false
console.log(!!1); // true
Giờ thì bạn đã có cái nhìn sâu sắc hơn về những hiện tượng kỳ lạ của JavaScript. Hy vọng rằng bài viết này giúp bạn trong việc hiểu rõ hơn về ngôn ngữ lập trình hấp dẫn này và tránh những cạm bẫy phổ biến trong quá trình phát triển mã.
source: viblo