Nội dung bài viết
Video học lập trình mỗi ngày
isNaN() và Number.isNaN() trong javascript gây nhiều nhầm lẫn cho các devjs mới thậm chí là những devjs có nhiều kinh nghiệm. Nếu bạn trả lời câu hỏi này một các rành mạch thì không cần đọc bài viết này nữa, ngược lại thì bạn nên dành thời gian tìm hiểu isNaN trong javascript là gì? Và xin nhớ đây là một trong những bài viết Series - Mẹo viết javascript.
Number.isNaN và isNaN khác nhau như thế nào?
Trước tiên hãy xem ví dụ sau:
console.log(isNaN(NaN)) console.log(isNaN('Anonystick.com')) console.log(isNaN(undefined)) console.log(isNaN({})) console.log(Number.isNaN(NaN)) console.log(Number.isNaN('Anonystick.com')) console.log(Number.isNaN(undefined)) console.log(Number.isNaN({}))
Dừng lại tầm 1 phút, để cho bạn nhìn, suy nghĩ và trả lời. Cố thử xem mình trả lời đúng được mấy câu? Nếu đúng hết, bạn có thể leave, còn không hãy theo dõi tại sao mình lại sai. Câu trả lời như sau:
console.log(isNaN(NaN)) //true console.log(isNaN('Anonystick.com')) //true console.log(isNaN(undefined)) //true console.log(isNaN({})) //true console.log(Number.isNaN(NaN)) //true console.log(Number.isNaN('Anonystick.com')) //false console.log(Number.isNaN(undefined)) //false console.log(Number.isNaN({})) //false
Tại sao cùng một hàm trông giống nhau, nhưng tại sao kết quả lại khác nhau? Từ từ phân tích
NaN là gì?
Trước khi giải thích về NaN, thì điều kiện tiên quyết là phải hiểu về 7 kiểu dữ liệu trong javascript. Qua bài viết trước thì chúng ta biết được Trong JavaScript, có 7 loại giá trị, và cần hiểu thêm một khái niệm nữa đó là var (biến). Xem phần đầu tiên của bài viết về kiểu dữ liệu.
Thuộc tính global NaN có giá trị đại diện cho khái niệm Not-A-Number (Không-phải-Số). - Theo MDN.
Như vậy đủ để bạn hiểu hay chưa? Tôi thấy vẫn còn mơ hồ khi đọc. Để hiểu rõ hơn bạn có thể tìm hiểu từ "You don't know js", ở đó họ giải thích một cách rõ ràng hơn.
Đại khái là NaN là theo nghĩa đen là viết tắt của "Not a Number" nhưng với mô tả này gây hiểu nhầm cho nên sẽ chính xác hơn nhiều nếu coi NaN là "Number không hợp lệ" thì có vẻ tường minh hơn. Như vậy, chúng ta có thể hiểu là NaN chính là một giá trị mà giá trị đó là kiểu số.
Vậy câu hỏi đặt ra là làm thế nào để đánh giá một giá trị có phải là NaN hay không?
isNaN JavaScript
Vì sao lại có isNaN(), bạn hãy xem một code nhỏ dưới đây
NaN === NaN; //false
Ngay cả khi so sánh với bản thân nó mà vẫn return về false, lý do rất đơn giản là "NaN được đặc tả là không bao giờ bằng với một đối tượng hay một giá trị nào đó". Nếu bạn là một người tìm tòi và học hỏi thì câu trả lời nằm đây "Why is NaN === NaN false?"
Chính vì vậy isNaN() ra đời để làm việc đó. Chúng ta cần một hàm đặc biệt để xác định xem một giá trị có phải là NaN hay không. isNaN() Hóa ra là như vậy. Sửa lại ví dụ trên
isNaN(NaN); // true
Có vẻ trơn tru nhưng nhìn lại ví dụ ở trên cùng hay xem
isNaN('Anonystick.com'); // true isNaN(undefined); // true isNaN({}); // true
Nhìn sơ qua chúng ta thấy không phải là giá trị NaN nhưng vẫn return về true. Ngộ thật. Mà ngộ nha, BUG này tồn tại lâu rồi, nhưng giờ vần vậy. Chính vì vậy, những ai theo dõi blog javascript thì có thể thấy kể từ khi ES6 được Release thì có một phương pháp đó là Number.isNaN(). Có thể giúp chúng ta fix bug trong javascript này.
Number.isNaN(NaN); // true Number.isNaN('Anonystick'); // false Number.isNaN(undefined); // false Number.isNaN({}); // false
Nhìn lại ví dụ trên, bạn có thể hiểu vấn đề đã được khắc phục.
Polyfill Number.isNaN ()
Giả sử nếu bạn đã miss cơ hội học những tính năng ES6 javascript cực kỳ quan trọng thì có lẽ bạn đã bị lỗi thời. Thế nhưng, tôi sẽ giúp bạn giải quyết vấn đề này, nhưng tôi khuyên bạn nên học lại ES6 tới ES12. Tại sao lại cần viết polyfill thì chúng ta đã thảo luận ở bài trước.
if (!Number.isNaN) { Number.isNaN = function(n) { return ( typeof n === "number" && window.isNaN( n ) ); }; }
Có một cách triển khai đơn giản hơn
if (!Number.isNaN) { Number.isNaN = function(n) { return n !== n; }; }
Tóm lại
Number.isNaN() sinh ra từ ES6 để giải quyết BUG tồn tại trên 20 năm qua của javascript. Đó là lý do, vì sao chúng ta nên sử dụng và tham khảo những cú pháp mới nhất của ES6 tới ES11 kể từ khi nó ra đời.