NaN === NaN có dụng không vì sao

Trong tin học, NaN, (viết tắt của từ tiếng Anh not a number - không phải số), là một giá trị của kiểu dữ liệu số, biểu diễn một giá trị không xác định hoặc không thể biểu diễn, nó thường gặp trong các phép tính dấu phẩy động. NaN được giới thiệu trong chuẩn dấu phẩy động IEEE 754 năm 1985, cùng với việc biểu diễn các số không đếm được như vô tận.

Có hai loại NaN: NaN tĩnh và tín hiệu NaN. NaN tĩnh dùng báo lỗi khi gặp một phép toán hoặc giá trị không hợp lệ, trong khi tín hiệu NaN có thể cung cấp những chức năng nâng cao như đại số máy tính hoặc những phép toán mở rộng trên số thực dấu phẩy động. Ví dụ 0/0 không được định nghĩa là một số thực, do đó nó được biểu diễn bằng NaN; căn bậc hai của một số âm là số ảo, không thể biểu diễn bằng một số thực dấu chấm động, do đó biểu diễn bằng NaN, NaN có thể được dùng để biểu diễn những giá trị còn thiếu trong tính toán[1][2]

Số thực dấu phẩy động

Chú thích

  1. ^ Bowman, Kenneth (2006) An introduction to programming with IDL: Interactive Data Language. Academic Press. p. 26 ISBN 0-12-088559-X
  2. ^ William H. Press, Saul A. Teukolsky, William T. Vetterling (2007) Numerical recipes: the art of scientific computing.p. 34 Cambridge University Press, ISBN 0-521-88068-8

Lấy từ “https://vi.wikipedia.org/w/index.php?title=NaN&oldid=68203766”

Tác giả: Kuba Michalski

Nếu bạn đang dấn thân vào JavaScript, một trong những thứ bạn cần học đầu tiên chính là các loại data. Như khi chúng ta nói về Numbers, Strings và Booleans khá rõ ràng, các object cũng ổn nhưng khi null và indentified nhập cuộc thì mọi thứ sẽ trở nên rối hơn một chút.

Nếu bạn muốn hiểu rõ các ví dụ dưới đây, hãy mở DevTools Console bằng cách nhấn Ctrl+Shift+J (Windows / Linux) or Cmd+Opt+J (Mac).

NaN === NaN có dụng không vì sao

null value đại diện cho reference dẫn đến môt object hoặc address không tồn tại hoặc không có giá trị (source: MDN). Cho dù dẫn đến một thứ không tồn tại, bản thân nó lại là một global object (và là một trong những value đầu tiên của JavaScript).

NaN === NaN có dụng không vì sao

Phủ nhận null sẽ return true, nhưng khi so sánh nó với false (hoặc cả true) thì đưa về false.

NaN === NaN có dụng không vì sao

Theo công thức toán căn bản, null value chuyển về 0.

NaN === NaN có dụng không vì sao

undefined property đại diện cho giá trị ban đầu undefined. Đây là một trong những type nguyên thủy của JavaScript (nguồn: MDN). Căn bản nó nói rằng một cái gì đó không xác định được. Bạn có thể xem ví dụ sau, hiển thị giá trị của một biến mà trước đó không được gán giá trị.

NaN === NaN có dụng không vì sao

Khi bạn nêu biến nhưng không nêu giá trị cho nó, JavaScript sẽ gán giá trị “undefined” cho nó.

NaN === NaN có dụng không vì sao
Nếu bạn thử theo phương pháp toán tin bằng undefined, bạn sẽ nhận về NaN. Tương tự như null, phủ nhận undefined sẽ trả về true, nhưng so nó với hoặc true hoặc false sẽ trả về false.
NaN === NaN có dụng không vì sao

  • Cả hai khi bị phủ nhận đều tra về true, nhưng không có cái nào bằng true hoặc false.
  • Chúng đều đại diện cho một cái gì đó không tồn tại…
  • null đại diện cho “nothing”, hoàn toàn không tồn tại, không xác định được thứ không được xác định.
  • undefined thì có dạng data của riêng nó (undefined), null thì chỉ là một object
  • null đưa về 0 khi vận hành bằng toán, undefined trả về NaN

Ngoài ra còn một vài thứ khác cần lưu ý.

NaN === NaN có dụng không vì sao

Dòng đầu tiên: undefined == null, trả về true vì JavaScript cố gắng chuyển đổi cả hai giá trị về cùng loại.

Dòng thứ hai: undefined === null, cho chúng ta biết “Hãy so sánh với các loại data” (căn bản là check xem cả hai có giống nhau không) và JavaScript cũng đủ thông minh để thấy được sự khác biệt nên nó trả về “false”.

Và dòng cuối cùng: !undefined === !null, cái này thì đơn giản hơn. Vì cả hai giá trị bị phủ nhận đều trả về true, bạn có hai giá trị true, thì cuối cùng nó là true.

Nghe có vẻ hơi sai sai, và thật ra, đó là cái hay của ngôn ngữ này.

Vậy nếu như NaN tự so và trả về false, vậy thì ta có so nó với cái gì đi nữa cũng sẽ trả về false. May thay là chúng ta có một function để check xem nó có phải NaN hay không — isNaN().

NaN === NaN có dụng không vì sao

let là một variable block scoped.

Giá trị null đại diện cho nothing, một object hoặc address không tồn tại hoặc không có giá trị. Nó chuyển đổi từ 0 trong phương pháp vận hành toán đơn giản và là một global object.
null == false cho chúng ta false.

Property global undefined  đại diện cho gá trị ban đầu undefined. Nó cho biết một cái không được gán giá trị; không được xác định. undefined không chuyển đổi bất cứ gì thành số, nên khi dùng nó dùng tính toán số học sẽ trả về NaN.

NaN (Not-A-Number) đại diện một cái không phải là số, mặc dù bản thân nó thật ra là một số. Nó không bằng chính nó và để check xem có NaN không chúng ta sẽ dùng isNaN() function.

Tất cả những cái trên đều là các giá trị mang tính false nên nó sẽ trả về false.

JavaScript rất giỏi chuyển đổi giá trị vì thế bạn cần phải dùng dấu bằng đến 3 lần (===) để đảm bảo cả hai elements không giống nhau.

Bài viết gốc được đăng tải tại codeburst.io

Có lẽ rằng trong khi lập trình nói chung và nhất là với Javascript nói riêng đã không ít lần chúng ta gặp trường hợp một biến của chúng ta trả về một kiểu dữ liệu không mấy đẹp đẽ lắm là NaN. Những người chưa hiểu sâu về nó thường nghĩ ngay đến đã có gì đó sai sai trong xử lý mà dẫn đến kiểu dữ liệu này, hay đây là một loại thông báo lỗi mới, hay là do ăn ở... Tất nhiên chúng ta không thể trả lời một vấn đề kĩ thuật bằng những lý do rất "thiểu năng" như thế được. Chính vì thế nên chúng ta mới ngồi đây cùng nhau tìm hiểu rõ hơn. Rốt cuộc thì NaN nó là gì, khi nào nó xuất hiện và chúng ta sẽ xử lý nó như thế nào. OK bắt đầu thôi.

NaN là gì nhỉ?

Đầu tiên, NaN không phải là một từ khóa trong JavaScript giống như true, false, null ... mà nó là một thuộc tính của global object. Giá trị của NaN giống như giá trị của Number.NaN:

NaN; Number.NaN;

Vậy chúng ta có thể thấy rằng NaN được xem như một kiểu Number. Lý do tại sao thì chúng ta sẽ cùng nhau thảo luận trong các phần tiếp theo của bài viết này. Để kiểm chứng điều đó chúng ta hoàn toàn có thể sử dụng từ khóa typeof. Cách đơn giản nhất là hãy bật ngay cửa sổ console của trình duyệt lên và thử gõ vào đoạn lệnh sau:

typeof NaN 'number'

OK, kết quả hiển thị cho thấy NaN được xem như một kiểu Number. Vậy NaN có thể xuất hiện trong các trường hợp nào. Hãy cùng nhau khám phá tiếp nhé

Các cách để phát sinh NaN

  • Lấy số 0 chia cho số 0
  • Lấy vô cùng (infinity) chia cho vô cùng (infinity)
  • Nhân vô cùng (infinity) với số 0
  • Bất kỳ phép tính toán nào trong đó NaN là một toán hạng
  • Chuyển đổi một xâu non-numeric hoặc undefined về dạng number

Tại sao kiểu dữ liệu của NaN là 'number'?

Như định nghĩa, NaN là giá trị trả về từ một biểu thức mà kết quả là số không được xác định (undefined numerical). Tức là nó vẫn là kiểu dữ liệu numeric, tuy nhiên nó chưa xác định như một kiểu số thực. Chính vì thế nên trong JavaScript, ngoài việc trở thành một thành phần trong global object, nó còn là một thành phần của Number object. Ngoài ra NaN cũng đại diện cho bất kì số nào thuộc ngoài khoảng biểu diễn của miền giá trị cho phép theo chuẩn ECMAScript. Bây giờ chúng ta sẽ cùng nhau thảo luận một số vấn đề liên quan đến NaN nhé.

Sự giới hạn của số học máy tính

Chúng ta cùng xem xét biểu thức sau:

(3.2317006071311 * 10e616) / (3.2317006071311 * 10e616);

Biểu thức trên cho giá trị là NaN. Đẻ giải thích vấn đề này, Wikipedia có viết:

Computer arithmetic cannot directly operate on real numbers, but only on a finite subset of rational numbers, limited by the number of bits used to store them.

Theo như giải thích từ Wikipedia, vấn để ở chỗ máy tính không thể tính toán trực tiếp các giá trị của các số thực nếu vượt quá giới hạn cho phép, chính vì do giới hạn số lượng các bits sử dụng để lưu trữ các giá trị trong biểu thức đó. Chúng ta cùng nhau xem xét đến biểu thức trên. Theo thứ tự thực hiện của biểu thức. Đầu tiên nó sẽ tính toán giá trị của 3.2317006071311 * 10616 là một số thực. Tuy nhiên theo quy định của chuẩn ECMAScript thì giá trị của số này quá lớn, vượt quá giá trị của Number.MAX_VALUE và nó được biểu diễn dưới kiểu dữ liệu là vô cùng (Infinity). Tương tự biểu thức (3.2317006071311 * 10e616) cũng trả về dữ liệu dạng (Infinity). Theo như định nghĩa ở phần trên, kết quả của biểu thức sẽ trả về NaN. Trong trường hợp này, NaN được dùng để biểu diễn một giá trị không thể tính toán được bằng số học máy tính

NaN không có thứ tự

Theo như chuẩn IEEE 754, mọi phép so sánh với NaN luôn luôn trả về một kết quả là false. Điều này có nghĩa rằng, NaN không thể so sánh bằng, lớn hơn, hay nhỏ hơn bất kì số nào, kể cả chính nó. Chúng ta có thể xem xét các biểu thức sau để hiểu rõ hơn vấn đề:

NaN < 1; NaN > 1; NaN == NaN; isNaN(NaN);

Vì vậy để so sánh một giá trị trả về của một biểu thức là NaN hay không chúng ta phải sử dụng hàm isNaN() thay vì sử dụng toán tử == thông thường. Chúng ta cũng có thể tự định nghĩa lại một hàm isNaN() cho riêng mình như sau:

function isNaN(x) { x = Number(x); return x != x; }

Đơn giản và dễ hiểu phải không nào.

Đừng nhầm lẫn Boolean và NaN

Chúng ta cùng thử xem xét đoạn code sau:

isNaN(true); isNaN(false);

Boolean là một kiểu dữ liệu sử dụng bit nhị phân để biểu diễn giá trị. Nếu chúng ta ép kiểu nó sang kiểu Number nó sẽ có kết quả như sau:

Number(true); Number(false);

Và rõ ràng nó là các kiểu Number xác định, hoàn toàn khác với khái niệm của NaN Tổng kết Qua bài viết, mình đã trình bày khái niệm và một số vấn đề cần thảo luận về NaN. Hi vọng rằng nó giúp các bạn hiểu hơn về kiểu dữ liệu này và có nhiều cách xử lý linh hoạt hơn trong các trường hợp phải làm việc với NaN trong Javascript bạn nhé.