Javascript nan ошибка

NaN в JavaScript

От автора: В данной статье мы познакомимся со специальным свойством NaN (Not-A-Number), которое является значением, представляющим не-число.

Тип числа в JavaScript содержит целые числа и числа с плавающей запятой:

const integer = 4;

const float = 1.5;

typeof integer; // => ‘number’

typeof float;   // => ‘number’

Плюс есть два специальных числовых значения: Infinity (число больше, чем любое другое число) и NaN (представляющее концепцию «не число»):

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

const infinite = Infinity;

const faulty = NaN;

typeof infinite; // => ‘number’

typeof faulty;   // => ‘number’

Хотя непосредственная работа с NaN редко встречается, оно может неожиданно появиться после неудачной операции с числами.

Давайте подробно рассмотрим специальное значение NaN: как проверить, содержит ли переменная NaN, и сценарии, которые в которых генерируется значения «не число».

1. Число NaN

Тип числа в JavaScript — это набор всех числовых значений, включая «не число», положительную бесконечность и отрицательную бесконечность.

«Not A Number» можно получить с помощью специального выражения NaN или как свойство глобального объекта или функции Number:

typeof NaN;        // => ‘number’

typeof window.NaN; // => ‘number’

typeof Number.NaN; // => ‘number’

«Не число» — это значение, которое не представляет действительное число, несмотря на то, что оно имеет тип числа. Через NaN полезно представлять ошибочные операции с числами. Например, умножение числа на undefined не является допустимой операцией, поэтому дает NaN:

Также попытка разобрать недопустимую числовую строку, например, ‘Joker’ приводит к NaN:

parseInt(‘Joker’, 10); // => NaN

2. Проверка на равенство с NaN

Интересным свойством NaN является то, что оно не равно ни одному значению, даже самому себе:

Это поведение полезно для определения, является ли переменная NaN:

const someNumber = NaN;

if (someNumber !== someNumber) {  console.log(‘Is NaN’);

} else {

  console.log(‘Is Not NaN’);

}

// logs «Is NaN»

Выражение someNumber !== someNumber равно true, только если someNumber является NaN. Таким образом, приведенный выше фрагмент регистрирует в консоли «Is NaN». JavaScript содержит встроенные функции для определения NaN: isNaN() и Number.isNaN():

isNaN(NaN); // => true

isNaN(1);   // => false

Number.isNaN(NaN); // => true

Number.isNaN(1);   // => false

Разница между этими функциями заключается в том, что Number.isNaN() не преобразуется свой аргумент в число:

isNaN(‘Joker12’);        // => true

Number.isNaN(‘Joker12’); // => false

isNaN(‘Joker12’) преобразует аргумент ‘Joker12’ в число, которое является NaN. Таким образом, функция возвращает true.

С другой стороны, Number.isNaN(‘Joker12’) проверяет аргумент без преобразования. Функция возвращает false, потому ‘Joker12’ не равно NaN.

3. Операции, дающие NaN

3.1 Парсинг чисел

В JavaScript вы можете преобразовать числовые строки в числа. Например, вы можете легко преобразовать строку ‘1.5’ в число с плавающей запятой 1.5:

const numberString = ‘1.5’;

const number = parseFloat(numberString);

number; // => 1.5

Когда строка не может быть преобразована в число, функция синтаксического анализа возвращает NaN: указывая, что синтаксический анализ не выполнен. Вот некоторые примеры:

parseFloat(‘Joker12.5’); // => NaN

parseInt(‘Joker12’, 10); // => NaN

Number(‘Joker12’);       // => NaN

При парсинге чисел рекомендуется проверить, не является ли результат парсинга NaN:

let inputToParse = ‘Invalid10’;

let number;

number = parseInt(inputToParse, 10);

if (isNaN(number)) {  number = 0;

}

number; // => 0

Парсинг inputToParse не удался, поэтому parseInt(inputToParse, 10) возвращается NaN. Условие if (isNaN(number)) оценивается, как true, и 0 назначается number.

3.2 undefined в качестве операнда

При использовании undefined в качестве операнда в арифметических операциях, таких как сложение, умножение и т д. мы получаем NaN. Например:

function getFontSize(style) {

  return style.fontSize;

}

const fontSize = getFontSize({ size: 16 }) * 2;

const doubledFontSize = fontSize * 2;

doubledFontSize; // => NaN

getFontSize() — это функция, которая обращается к свойству fontSize из объекта стиля. При вызове getFontSize({ size: 16 }) результатом будкт undefined (свойство fontSize не существует в объекте { size: 16 }). fontSize * 2 оценивается как undefined * 2, что дает NaN.

«Not A Number» генерируется, когда в качестве значения в арифметических операциях используется отсутствующее свойство или функция, возвращающая undefined. Отсутствие undefined в арифметических операциях — это хороший способ предотвратить получение NaN.

3.3 NaN как операнд

Значение NaN также генерируется, когда операндом в арифметических операциях является NaN:

1 + NaN; // => NaN

2 * NaN; // => NaN

NaN распространяется на арифметические операции:

let invalidNumber = 1 * undefined;

let result = 1;

result += invalidNumber; // appendresult *= 2;             // duplicate

result++;                // increment

result; // => NaN

Операции с переменной result прерываются после добавления к result значения invalidNumber (которое является NaN).

3.4 Неопределенные формы

Значение NaN создается, когда арифметические операции имеют неопределенные формы. Деление 0 / 0 и Inifinity / Infinity:

0 / 0;               // => NaN

Infinity / Infinity; // => NaN

Умножение 0 и Infinity:

Сложение бесконечных чисел с разными знаками:

Infinity + Infinity; // => NaN

3.5 Неверные аргументы математических функций

Квадратный корень из отрицательного числа:

Math.pow(2, 0.5); // => NaN

(2) ** 0.5;       // => NaN

Или логарифм отрицательного числа:

4. Заключение

Понятие «не число», выраженное в JavaScript с помощью NaN, полезно для представления ошибочных операций над числами. NaN не равно ни одному значению, даже самому себе. Рекомендуемый способ проверить, содержит ли переменная NaN — использовать Number.isNaN(value).

Преобразование числовых строк в числа, в случае неудачи может дать NaN. Рекомендуется проверять, не возвращают ли parseInt(), parseFloat() или Number() NaN.

Если undefined или NaN используются в качестве операнда в арифметических операциях, это обычно приводит к NaN. Правильная обработка undefined (предоставление значений по умолчанию для отсутствующих свойств) является рекомендованным подходом для предотвращения этой ситуации.

Неопределенные формы или недопустимые аргументы для математических функций также приводят получению NaN. Но это случается редко. Вот мой практический совет: «Получили NaN? Ищите undefined!»

Автор: Dmitri Pavlutin

Источник: //dmitripavlutin.com

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

Редакция: Команда webformyself.

Some definitions from W3Schools:

Infinity: A numeric value that represents positive/negative infinity

The POSITIVE_INFINITY property represents infinity, returned on overflow.
NEGATIVE_INFINITY, represents negative infinity (returned on overflow).

The NaN property represents «Not-a-Number» value. This property indicates that a value is not a legal number.

The isFinite() function determines whether a number is a finite, legal number.
This function returns false if the value is +infinity, -infinity, or NaN.

Some tests:

 var n1 = 1/0;
  var n2 = 0/0;
  var n3 = (Number.MAX_VALUE)*2; //overflow

  var b1 = Number.POSITIVE_INFINITY == n1;
  var b2 = Number.POSITIVE_INFINITY == n2;
  var b2n = Number.NEGATIVE_INFINITY == n2;
  var b3 = Number.POSITIVE_INFINITY == n3;

  var msg = "n1=" + n1 + ", n2=" + n2 + ", n3=" + n3;

  msg += "<br/> n1 Is POSITIVE_INFINITY=" + b1;
  msg += "<br/> n2 Is POSITIVE_INFINITY=" + b2;
  msg += "<br/> n2 Is POSITIVE_INFINITY=" + b2n;
  msg += "<br/> n3 Is POSITIVE_INFINITY=" + b3;

  msg += "<br/> n1 IsFinite=" + isFinite(n1);
  msg += "<br/> n2 IsFinite=" + isFinite(n2);
  msg += "<br/> n3 IsFinite=" + isFinite(n3);


  msg += "<br/> n1 + n1 =" + (n1 + n1) ;
  msg += "<br/> n1 - n1 =" + (n1 - n1) ;
  msg += "<br/> n2 + n1 =" + (n2 + n1) ;

  document.write(msg);

Shows

n1=Infinity, n2=NaN, n3=Infinity
n1 Is POSITIVE_INFINITY=true
n2 Is POSITIVE_INFINITY=false
n2 Is POSITIVE_INFINITY=false
n3 Is POSITIVE_INFINITY=true
n1 IsFinite=false
n2 IsFinite=false
n3 IsFinite=false
n1 + n1 =Infinity
n1 - n1 =NaN
n1 - n1 =NaN

Cover image for What is an NaN error in JavaScript?

keyboard

Have you ever wondered what is NaN error coming in your project? 🤔

Today, in this article I am going to discuss the NaN error in detail.

Let’s get started 🚀

In JavaScript, NaN stands for Not a Number.
This error occurs when you parse something to a number that is not a number

Let’s see it with an example,

var helloWorld = parseInt(helloWorld);

Enter fullscreen mode

Exit fullscreen mode

This will return NaN

didn’t get it? No problem let’s get a little simpler

var helloWorld = parseInt("Hello World");

Enter fullscreen mode

Exit fullscreen mode

"Hello World" is a string and we are parsing to an integer but that is not possible therefore the browser will return NaN

isNan() Method

isNan() will return true if a value is NaN
example

isNaN(18)
// false
isNaN(18.81)
// false
isNaN("JavaScript")
// true
isNaN("233.3")
// false
isNaN('17/01/2022')
// true

Enter fullscreen mode

Exit fullscreen mode

As you can see numbers will return false as they are not NaN even if, the number is in the form of string.
Any string (word or sentence) will return true as it is NaN

Me when isNaN("123") showing false:
confusing

What about you? Comment 👇

wait a minute

Here comes, something that contradicts

As discussed earlier, isNan() will return true if a value is Not-a-Number(NaN)
Number.isNaN() method while is completely opposite of isNaN method, here Number.isNaN() will return true if number is NaN

Let’s go with an example,

isNaN('JavaScript')
// true
Number.isNaN('JavaScript')
// false

Enter fullscreen mode

Exit fullscreen mode

isNaN(18)
// false
Number.isNaN(18)
// true

Enter fullscreen mode

Exit fullscreen mode


Thank you for reading, have a nice day!

  • Follow me on Twitter — @codewithsnowbit
  • Subscribe me on YouTube — Code With SnowBit
    Have a nice day.png

Время на прочтение
6 мин

Количество просмотров 145K

Мне очень нравится JavaScript и я считаю его мощным и удобным. Но для большинства начинающих JS-программистов, много проблем создаёт недопонимание аспектов языка. Часто конструкции языка ведут себя «нелогично». В данной статье я хочу привести примеры «граблей», на которые я наступил; объяснить поведение языка и дать пару советов.

Типы

Как написано в спецификации ECMAScript, всего существует 6 типов:

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Object

Все значения должны принадлежать к ним. В JS есть оператор typeof, который, как казалось бы, должен возвращать тип объекта. Казалось бы, один из перечисленных. Что получается на самом деле:

  typeof 5;             //"number",        ок, похоже на правду
  typeof "hello";       //"string" 
  typeof true;          //"boolean" 
  typeof undefined;     //"undefined"
  typeof {};            //"object".        Пока 5 из 5
  typeof null;          //"object".        WTF?
  typeof function(){};  //"function".      Разве у нас есть тип function?

Проблема: несмотря на то, что тип у null — Null, оператор возвращает ‘object’; а тип у функции — Object, оператор возвращает ‘function’, а такого типа нет.
Объяснение: typeof возвращает не тип, а строку, которая зависит от аргумента и не является именем типа.
Совет: забудьте про типы. Серьезно, я считаю что знание 6 типов JS не даст вам пользы, а оператор typeof используется довольно часто, поэтому лучше запомнить результаты его работы:

Тип аргумента Результат
Undefined undefined
Null object
Boolean boolean
Number number
String string
Object (результаты оператора new, inline-объекты ({key: value})) object
Object (функции) function

Магические значения: undefined, null, NaN

В спецификации описаны так:

  • undefined value — primitive value used when a variable has not been assigned a value
  • Undefined type — type whose sole value is the undefined value
  • null value — primitive value that represents the intentional absence of any object value
  • Null type — type whose sole value is the null value
  • NaN — number value that is a IEEE 754 “Not-a-Number” value

У себя в голове я держу следующее:

  • undefined — значение переменной, которая не была инициализирована. Единственное значение типа Undefined.
  • null — умышленно созданный «пустой» объект. Единственное значение типа Null.
  • NaN — специальное значение типа Number, для выражения «не чисел», «неопределенности». Может быть получено, например, как результат деления 0 на 0 (из курса матанализа помним, что это неопределенность, а деление других чисел на 0 — это бесконечность, для которой в JS есть значения Infinity).

С этими значениями я обнаружил много «магии». Для начала, булевы операции с ними:

  !!undefined; //false
  !!NaN; //false
  !!null; //false
  //как видим, все 3 значения при приведении к boolean дают false

  null == undefined; //true

  undefined === undefined; //true
  null === null; //true

  NaN == undefined; //false
  NaN == null; //false

  NaN === NaN; //false!
  NaN == NaN; //false!

Проблема: с чем бы мы ни сравнивали NaN, результатом сравнения всегда будет false.
Объяснение: NaN может возникать в результате множества операций: 0/0, parseInt(‘неприводимая к числу строка’), Math.sqrt(-1) и было бы странно, если корень из -1 равнялся 0/0. Именно поэтому NaN !== NaN.
Совет: не использовать булевы операторы с NaN. Для проверки нужно использовать функцию isNaN.

  typeof a; //'undefined'
  a; //ReferenceError: a is not defined

Проблема: оператор typeof говорит нам, что тип необъявленной переменной — undefined, но при обращении к ней происходит ошибка.
Объяснение: на самом деле, есть 2 понятия — Undefined и Undeclared. Так вот, необъявленная переменная является Undeclared-переменной и обращение к ней вызывает ошибку. Объявленная, но не инициализированная переменная принимает значение undefined и при обращении к ней ошибок не возникает.
Совет: перед обращением к переменной, вы должны быть уверенны, что она объявлена. Если вы обратитесь к Undeclared-переменной, то код, следующий за обращением, не будет выполнен.

  var a; //вновь объявленная переменная, для которой не указано значение, принимает значение undefined
  console.log(undefined); //undefined
  console.log(a); // undefined
  a === undefined; //true
  undefined = 1;
  console.log(undefined); //1
  a === undefined; //false

Проблема: в любой момент мы можем прочитать и записать значение undefined, следовательно, кто-то может перезаписать его за нас и сравнение с undefined будет некорректным.
Объяснение: undefined — это не только значение undefined типа Undefined, но и глобальная переменная, а значит, любой может её переопределить.
Совет: просто сравнивать переменные с undefined — плохой тон. Есть 3 варианта решения данной проблемы, для создания «пуленепробиваемого» кода.

  • Вы можете сравнивать не значение переменной, а её тип: «typeof a === ‘undefined’».
  • Использовать паттерн immediately-invoked function:

  (function(window, undefined){
    //т.к. второй аргумент не был передан, значение переменной undefined будет «правильным».
  }(this));

  • Для получения реального «undefined»-значения можно использовать оператор void (кстати, я не знаю другого применения этому оператору):

  typeof void(0) === 'undefined' // true

Теперь попробуем совершить аналогичные действия с null:

  console.log(null); //null
  null = 1; //ReferenceError: Invalid left-hand side in assignment

Проблема: несмотря на некоторые сходства между null и undefined, null мы перезаписать не можем. На самом деле проблема не в этом, а в том, что язык ведёт себя нелогично: даёт перезаписать undefined, но не даёт перезаписать null.
Объяснение: null — это не глобальная переменная и вы не можете её создать, т. к. null — зарезервированное слово.
Совет: в JavaScript не так много зарезервированных слов, проще их запомнить и не использовать как имена переменных, чем вникать, в чём проблема, когда она возникнет.

И теперь сделаем тоже самое с NaN:

  console.log(NaN); //NaN
  NaN = 1;
  console.log(NaN); //NaN
  isNaN(NaN); //true

Проблема: при переопределении undefined всё прошло успешно, при переопределении null возникла ошибка, а при переопределении NaN операция не вызвала ошибки, но свойство не было переопределено.
Объяснение: нужно понимать, что NaN — переменная глобального контекста (объекта window). Помимо этого, к NaN можно «достучаться» через Number.NaN. Но это неважно, ниодно из этих свойств вы не сможете переопределить, т. к. NaN — not writable property:

  Object.getOwnPropertyDescriptor(window, NaN).writable; //false
  Object.getOwnPropertyDescriptor(Number, NaN).writable; //false

Совет: как JS-программисту, вам нужно знать об атрибутах свойств:

Атрибут Тип Смысл
enumerable Boolean Если true, то данное свойство будет участвовать в циклах for-in
writable Boolean Если false, то значение этого свойства нельзя будет изменить
configurable Boolean Если false, то значение этого свойства нельзя изменить, удалить и изменить атрибуты свойства тоже нельзя
value Любой Значение свойства при его чтении
get Object (или Undefined) функция-геттер
set Object (или Undefined) функция-сеттер

Вы можете объявлять неудаляемые или read-only свойства и для созданных вами объектов, используя метод Object.defineProperty:

  var obj = {};
  Object.defineProperty(obj, 'a', {writable: true,  configurable: true,  value: 'a'});
  Object.defineProperty(obj, 'b', {writable: false, configurable: true,  value: 'b'});
  Object.defineProperty(obj, 'c', {writable: false, configurable: false, value: 'c'});

  console.log(obj.a); //a
  obj.a = 'b';
  console.log(obj.a); //b
  delete obj.a; //true

  console.log(obj.b); //b
  obj.b = 'a';
  console.log(obj.b); //b
  delete obj.b; //true

  console.log(obj.c); //c
  obj.b = 'a';
  console.log(obj.c); //c
  delete obj.b; //false

Работа с дробными числами

Давайте вспомним 3-й класс и сложим несколько десятичных дробей. Результаты сложения в уме проверим в консоли JS:

  0.5 + 0.5; //1
  0.5 + 0.7; //1.2
  0.1 + 0.2; //0.30000000000000004;
  0.1 + 0.7; //0.7999999999999999;
  0.1 + 0.2 - 0.2; //0.10000000000000003

Проблема: при сложении некоторых дробных чисел, выдаётся арифметически неверный результат.
Объяснение: такие результаты получаются из-за особенностей работы c числами с плавающей точкой. Это не является особенностью JavaScript, другие языки работают также (я проверил в PHP, Python и Ruby).
Совет: во-первых, вы, как программист, обязаны знать об особенностях работы компьютера с числами с плавающей точкой. Во-вторых, в большинстве случаев достаточно просто округлять результаты. Но, если вдруг необходимо выдавать пользователю точный результат, например, при работе с данными о деньгах, вы можете просто умножать все аргументы на 10 и результат делить обратно на 10, например так:

  function sum() {
    var result = 0;
    for (var i = 0, max = arguments.length; i< max; i++ ) {
      result += arguments[i]*10;
    }
    return result / 10;
  }
  sum(0.5, 0.5); //1
  sum(0.5, 0.7); //1.2
  sum(0.1, 0.2); //0.3
  sum(0.1, 0.7); //0.8
  sum(0.1, 0.2, -0.2); //0.1

Вывод

Это только несколько необычных примеров с непредсказуемым результатом. Если помнить о них, то получится не наступить на те же грабли и быстро понять, в чём проблема. Если найдёте новый «нелогичный» кусок кода, то попробуйте осознать, что происходит с точки зрения языка, почитав спецификацию или MDN.

Глобальное свойство NaN — это значение, представляющее Not-A-Number.

Атрибуты свойства NaN
Writable no
Enumerable no
Configurable no

Try it

Description

NaN — это свойство глобального объекта . Другими словами, это переменная в глобальной области видимости.

Начальное значение NaN равно Not-A-Number — то же, что и значение Number.NaN . В современных браузерах NaN является ненастраиваемым и недоступным для записи свойством. Даже если это не так, избегайте переопределения. NaN в программе довольно редко .

Существует пять различных типов операций, возвращающих NaN :

  • Число не может быть проанализировано (например, parseInt("blabla") или Number(undefined) )
  • Математическая операция, результат которой не является действительным числом (например, Math.sqrt(-1) )
  • Операнд аргумента — NaN (например, 7 ** NaN )
  • Неопределенная форма (например, 0 * Infinity или undefined + undefined )
  • Любая операция, которая включает строку и не является операцией сложения (например, "foo" / 3 )

Examples

Тестирование против NaN

NaN сравнивает unequal (через == , != , === и !== ) с любым другим значением, в том числе с другим значением NaN . Используйте Number.isNaN() или isNaN() , чтобы наиболее четко определить, является ли значение NaN . Или выполните самосравнение: NaN и только NaN будут сравниваться неравно самому себе.

NaN === NaN;        
Number.NaN === NaN; 
isNaN(NaN);         
isNaN(Number.NaN);  
Number.isNaN(NaN);  

function valueIsNaN(v) { return v !== v; }
valueIsNaN(1);          
valueIsNaN(NaN);        
valueIsNaN(Number.NaN); 

Однако обратите внимание на разницу между isNaN() и Number.isNaN() : первый вернет true если значение в настоящее время равно NaN , или если оно будет NaN после приведения его к числу, а последнее вернет true только если значение в настоящее время NaN :

isNaN('hello world');        
Number.isNaN('hello world'); 

По той же причине использование значения bigint вызовет ошибку с isNaN() , а не с Number.isNaN() :

isNaN(1n);        
Number.isNaN(1n); 

Кроме того, некоторые методы массива не могут найти NaN , а другие -.

const arr = [2, 4, NaN, 12];
arr.indexOf(NaN);                      
arr.includes(NaN);                     
arr.findIndex((n) => Number.isNaN(n));   

Specifications

Browser compatibility

Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox для Android Opera Android Safari на IOS Samsung Internet Deno Node.js
NaN

1

12

1

4

4

1

4.4

18

4

10.1

1

1.0

1.0

0.10.0

See also

  • Number.NaN
  • Number.isNaN()
  • isNaN()


JavaScript

  • Math.tanh()

    Функция Math.tanh()возвращает гиперболический тангенс числа,то есть tanh x sinh cosh e 2 1 frac{sinh x}{cosh {e^x frac{e^{2x}1}{e^{2x}+1}Число.

  • Math.trunc()

    Функция Math.trunc()возвращает целую часть числа,удаляя все дробные цифры.

  • Number

    Number-это примитивный объект-обертка,используемый для представления и манипулирования числами,такими как 37 -9.25.

  • Number.EPSILON

    Свойство Number.EPSILON представляет разницу между 1 и наименьшим значением с плавающей точкой больше чем Вы не должны создавать объект Number для доступа к этому свойству.

Like this post? Please share to your friends:
  • Javascript fetch обработка ошибок
  • Javascript error как устранить ошибку
  • Javascript error как убрать ошибку
  • Javascript console ошибка
  • Javascript await ошибка