- Подводные камни JavaScript
- Магические значения: undefined, null, NaN
- Работа с дробными числами
- Преобразование NaN в 0 в javascript
- 8 ответов
- Convert NaN to 0 in javascript
- 11 Answers 11
- NaN в JavaScript
- 1. Число NaN
- 2. Проверка на равенство с NaN
- 3. Операции, дающие NaN
- 3.1 Парсинг чисел
- 3.2 undefined в качестве операнда
- 3.3 NaN как операнд
- 3.4 Неопределенные формы
- 3.5 Неверные аргументы математических функций
- 4. Заключение
- JavaScript. Быстрый старт
Подводные камни JavaScript
Мне очень нравится JavaScript и я считаю его мощным и удобным. Но для большинства начинающих JS-программистов, много проблем создаёт недопонимание аспектов языка. Часто конструкции языка ведут себя «нелогично». В данной статье я хочу привести примеры «граблей», на которые я наступил; объяснить поведение языка и дать пару советов.
Как написано в спецификации ECMAScript, всего существует 6 типов:
- Undefined
- Null
- Boolean
- String
- Number
- Object
Все значения должны принадлежать к ним. В JS есть оператор typeof, который, как казалось бы, должен возвращать тип объекта. Казалось бы, один из перечисленных. Что получается на самом деле:
Проблема: несмотря на то, что тип у null — Null, оператор возвращает ‘object’; а тип у функции — Object, оператор возвращает ‘function’, а такого типа нет.
Объяснение: typeof возвращает не тип, а строку, которая зависит от аргумента и не является именем типа.
Совет: забудьте про типы. Серьезно, я считаю что знание 6 типов JS не даст вам пользы, а оператор typeof используется довольно часто, поэтому лучше запомнить результаты его работы:
Тип аргумента | Результат |
Undefined | undefined |
Null | object |
Boolean | boolean |
Number | number |
String | string |
Object (результаты оператора new, inline-объекты ( | 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).
С этими значениями я обнаружил много «магии». Для начала, булевы операции с ними:
Проблема: с чем бы мы ни сравнивали NaN, результатом сравнения всегда будет false.
Объяснение: NaN может возникать в результате множества операций: 0/0, parseInt(‘неприводимая к числу строка’), Math.sqrt(-1) и было бы странно, если корень из -1 равнялся 0/0. Именно поэтому NaN !== NaN.
Совет: не использовать булевы операторы с NaN. Для проверки нужно использовать функцию isNaN.
Проблема: оператор typeof говорит нам, что тип необъявленной переменной — undefined, но при обращении к ней происходит ошибка.
Объяснение: на самом деле, есть 2 понятия — Undefined и Undeclared. Так вот, необъявленная переменная является Undeclared-переменной и обращение к ней вызывает ошибку. Объявленная, но не инициализированная переменная принимает значение undefined и при обращении к ней ошибок не возникает.
Совет: перед обращением к переменной, вы должны быть уверенны, что она объявлена. Если вы обратитесь к Undeclared-переменной, то код, следующий за обращением, не будет выполнен.
Проблема: в любой момент мы можем прочитать и записать значение undefined, следовательно, кто-то может перезаписать его за нас и сравнение с undefined будет некорректным.
Объяснение: undefined — это не только значение undefined типа Undefined, но и глобальная переменная, а значит, любой может её переопределить.
Совет: просто сравнивать переменные с undefined — плохой тон. Есть 3 варианта решения данной проблемы, для создания «пуленепробиваемого» кода.
- Вы можете сравнивать не значение переменной, а её тип: «typeof a === ‘undefined’».
- Использовать паттерн immediately-invoked function:
- Для получения реального «undefined»-значения можно использовать оператор void (кстати, я не знаю другого применения этому оператору):
Теперь попробуем совершить аналогичные действия с null:
Проблема: несмотря на некоторые сходства между null и undefined, null мы перезаписать не можем. На самом деле проблема не в этом, а в том, что язык ведёт себя нелогично: даёт перезаписать undefined, но не даёт перезаписать null.
Объяснение: null — это не глобальная переменная и вы не можете её создать, т. к. null — зарезервированное слово.
Совет: в JavaScript не так много зарезервированных слов, проще их запомнить и не использовать как имена переменных, чем вникать, в чём проблема, когда она возникнет.
И теперь сделаем тоже самое с NaN:
Проблема: при переопределении undefined всё прошло успешно, при переопределении null возникла ошибка, а при переопределении NaN операция не вызвала ошибки, но свойство не было переопределено.
Объяснение: нужно понимать, что NaN — переменная глобального контекста (объекта window). Помимо этого, к NaN можно «достучаться» через Number.NaN. Но это неважно, ниодно из этих свойств вы не сможете переопределить, т. к. NaN — not writable property:
Совет: как JS-программисту, вам нужно знать об атрибутах свойств:
Атрибут | Тип | Смысл |
enumerable | Boolean | Если true, то данное свойство будет участвовать в циклах for-in |
writable | Boolean | Если false, то значение этого свойства нельзя будет изменить |
configurable | Boolean | Если false, то значение этого свойства нельзя изменить, удалить и изменить атрибуты свойства тоже нельзя |
value | Любой | Значение свойства при его чтении |
get | Object (или Undefined) | функция-геттер |
set | Object (или Undefined) | функция-сеттер |
Вы можете объявлять неудаляемые или read-only свойства и для созданных вами объектов, используя метод Object.defineProperty:
Работа с дробными числами
Давайте вспомним 3-й класс и сложим несколько десятичных дробей. Результаты сложения в уме проверим в консоли JS:
Проблема: при сложении некоторых дробных чисел, выдаётся арифметически неверный результат.
Объяснение: такие результаты получаются из-за особенностей работы c числами с плавающей точкой. Это не является особенностью JavaScript, другие языки работают также (я проверил в PHP, Python и Ruby).
Совет: во-первых, вы, как программист, обязаны знать об особенностях работы компьютера с числами с плавающей точкой. Во-вторых, в большинстве случаев достаточно просто округлять результаты. Но, если вдруг необходимо выдавать пользователю точный результат, например, при работе с данными о деньгах, вы можете просто умножать все аргументы на 10 и результат делить обратно на 10, например так:
Источник
Преобразование NaN в 0 в javascript
есть ли способ преобразовать значения NaN в 0 без оператора if:
очень раздражает проверять мои переменные каждый раз.
8 ответов
вы можете сделать это:
. который преобразует a из любого «falsey» значения в 0 .
или это если вы предпочитаю:
. который будет иметь тот же эффект, что и выше.
если намерение состояло в том, чтобы проверить больше, чем просто NaN , тогда вы можете сделать то же самое, но сделать toNumber преобразование первого.
это использует унарный оператор+, чтобы попытаться преобразовать a в число. Это имеет дополнительное преимущество преобразования таких вещей, как числовые строки ‘123’ в число.
единственная неожиданная вещь может быть если кто-то передает массив, который может быть успешно преобразован в число:
здесь мы имеем массив, который имеет один член, который является числовой строкой. Он будет успешно преобразован в число.
напишите свой собственный метод и используйте его везде, где вы хотите числовое значение:
использование двойной Тильды (двойной побитовой не) —
— делает некоторые интересные вещи в JavaScript. Например, вы можете использовать его вместо Math.floor или даже в качестве альтернативы parseInt(«123″, 10) ! Это обсуждалось много в интернете, поэтому я не буду вдаваться в то, почему он работает здесь, но если вам интересно: что такое оператор» двойной Тильды » (
мы можем использовать это свойство двойной Тильды для преобразования NaN к числу, и, к счастью, это число ноль!
вместо того, чтобы клаудировать его, чтобы вы могли продолжать, почему бы не вернуться и не задаться вопросом, почему вы столкнулись с Нан в первую очередь?
если любой из числовых входов в операцию NaN, выход также будет NaN. Так работает текущий стандарт IEEE с плавающей запятой (это не просто Javascript). Это поведение для причина: основное намерение состоит в том, чтобы удержать вас от использования фиктивного результата, не понимая, что это фикция.
путь NaN works-если что-то пойдет не так в какой-то суб-суб-суб-операции (производство NaN на этом более низком уровне), конечный результат будет и быть NaN, который вы сразу распознаете как ошибку, даже если ваша логика обработки ошибок (бросок/улов, возможно?) еще не завершена.
NaN в результате арифметического вычисления всегда указывает на то, что что-то пошло не так в деталях арифметики. Это способ для компьютера сказать «требуется отладка здесь.» Вместо того, чтобы найти способ продолжить в любом случае с некоторым числом, которое вряд ли когда-либо правильно (0 действительно то, что вы хотите?), почему бы не найти проблему и исправить ее.
общей проблемой в Javascript является то, что оба parseInt(. ) и parseFloat(. ) вернет NaN, если задан бессмысленный аргумент ( null , » и т. д.). Исправить проблему на низком уровне, а не на более высоком уровне. Тогда результат общего расчета имеет хорошие шансы иметь смысл, и вы не подставляя какое-то магическое число (0 или 1 или что-то еще) для результата всего вычисления. (Трюк (parseInt (foo.value) / / 0) работает только для сумм, а не для продуктов — для продуктов вы хотите, чтобы значение по умолчанию было 1, а не 0, но не если указанное значение действительно равно 0.)
возможно, для удобства кодирования вы хотите, чтобы функция получала значение от пользователя, очищала его и при необходимости предоставляла значение по умолчанию, например:
код ниже будет игнорировать NaN, чтобы позволить вычисление правильно введенных чисел
Источник
Convert NaN to 0 in javascript
Is there a way to convert NaN values to 0 without an if statement:
It is very annoying to check my variables every time.
11 Answers 11
You can do this:
. which will convert a from any «falsey» value to 0 .
The «falsey» values are:
Or this if you prefer:
. which will have the same effect as above.
If the intent was to test for more than just NaN , then you can do the same, but do a toNumber conversion first.
This uses the unary + operator to try to convert a to a number. This has the added benefit of converting things like numeric strings ‘123’ to a number.
The only unexpected thing may be if someone passes an Array that can successfully be converted to a number:
Here we have an Array that has a single member that is a numeric string. It will be successfully converted to a number.
Using a double-tilde (double bitwise NOT) —
— does some interesting things in JavaScript. For instance you can use it instead of Math.floor or even as an alternative to parseInt(«123», 10) ! It’s been discussed a lot over the web, so I won’t go in why it works here, but if you’re interested: What is the «double tilde» (
We can exploit this property of a double-tilde to convert NaN to a number, and happily that number is zero!
at all, I just used it along side with parseFloat() like so:
parseFloat($variable); . Very neat 🙂 +1
Write your own method, and use it everywhere you want a number value:
Something simpler and effective for anything :
. which will convert a from any «falsey» value to 0 .
The «falsey» values are:
The code below will ignore NaN to allow a calculation of properly entered numbers
Rather than kludging it so you can continue, why not back up and wonder why you’re running into a NaN in the first place?
If any of the numeric inputs to an operation is NaN, the output will also be NaN. That’s the way the current IEEE Floating Point standard works (it’s not just Javascript). That behavior is for a good reason: the underlying intention is to keep you from using a bogus result without realizing it’s bogus.
The way NaN works is if something goes wrong way down in some sub-sub-sub-operation (producing a NaN at that lower level), the final result will also be NaN, which you’ll immediately recognize as an error even if your error handling logic (throw/catch maybe?) isn’t yet complete.
NaN as the result of an arithmetic calculation always indicates something has gone awry in the details of the arithmetic. It’s a way for the computer to say «debugging needed here». Rather than finding some way to continue anyway with some number that’s hardly ever right (is 0 really what you want?), why not find the problem and fix it.
A common problem in Javascript is that both parseInt(. ) and parseFloat(. ) will return NaN if given a nonsensical argument ( null , » , etc). Fix the issue at the lowest level possible rather than at a higher level. Then the result of the overall calculation has a good chance of making sense, and you’re not substituting some magic number (0 or 1 or whatever) for the result of the entire calculation. (The trick of (parseInt(foo.value) || 0) works only for sums, not products — for products you want the default value to be 1 rather than 0, but not if the specified value really is 0.)
Perhaps for ease of coding you want a function to retrieve a value from the user, clean it up, and provide a default value if necessary, like this:
Источник
NaN в JavaScript
Дата публикации: 2020-02-06
От автора: В данной статье мы познакомимся со специальным свойством NaN (Not-A-Number), которое является значением, представляющим не-число.
Тип числа в JavaScript содержит целые числа и числа с плавающей запятой:
Плюс есть два специальных числовых значения: Infinity (число больше, чем любое другое число) и NaN (представляющее концепцию «не число»):
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Хотя непосредственная работа с NaN редко встречается, оно может неожиданно появиться после неудачной операции с числами.
Давайте подробно рассмотрим специальное значение NaN: как проверить, содержит ли переменная NaN, и сценарии, которые в которых генерируется значения «не число».
1. Число NaN
Тип числа в JavaScript — это набор всех числовых значений, включая «не число», положительную бесконечность и отрицательную бесконечность.
«Not A Number» можно получить с помощью специального выражения NaN или как свойство глобального объекта или функции Number:
«Не число» — это значение, которое не представляет действительное число, несмотря на то, что оно имеет тип числа. Через NaN полезно представлять ошибочные операции с числами. Например, умножение числа на undefined не является допустимой операцией, поэтому дает NaN:
Также попытка разобрать недопустимую числовую строку, например, ‘Joker’ приводит к NaN:
2. Проверка на равенство с NaN
Интересным свойством NaN является то, что оно не равно ни одному значению, даже самому себе:
Это поведение полезно для определения, является ли переменная NaN:
Выражение someNumber !== someNumber равно true, только если someNumber является NaN. Таким образом, приведенный выше фрагмент регистрирует в консоли «Is NaN». JavaScript содержит встроенные функции для определения NaN: isNaN() и Number.isNaN():
Разница между этими функциями заключается в том, что Number.isNaN() не преобразуется свой аргумент в число:
isNaN(‘Joker12′) преобразует аргумент ‘Joker12′ в число, которое является NaN. Таким образом, функция возвращает true.
С другой стороны, Number.isNaN(‘Joker12′) проверяет аргумент без преобразования. Функция возвращает false, потому ‘Joker12′ не равно NaN.
3. Операции, дающие NaN
3.1 Парсинг чисел
В JavaScript вы можете преобразовать числовые строки в числа. Например, вы можете легко преобразовать строку ’1.5′ в число с плавающей запятой 1.5:
Когда строка не может быть преобразована в число, функция синтаксического анализа возвращает NaN: указывая, что синтаксический анализ не выполнен. Вот некоторые примеры:
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
При парсинге чисел рекомендуется проверить, не является ли результат парсинга NaN:
Парсинг inputToParse не удался, поэтому parseInt(inputToParse, 10) возвращается NaN. Условие if (isNaN(number)) оценивается, как true, и 0 назначается number.
3.2 undefined в качестве операнда
При использовании undefined в качестве операнда в арифметических операциях, таких как сложение, умножение и т д. мы получаем 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:
NaN распространяется на арифметические операции:
Операции с переменной result прерываются после добавления к result значения invalidNumber (которое является NaN).
3.4 Неопределенные формы
Значение NaN создается, когда арифметические операции имеют неопределенные формы. Деление 0 / 0 и Inifinity / Infinity:
Умножение 0 и Infinity:
Сложение бесконечных чисел с разными знаками:
3.5 Неверные аргументы математических функций
Квадратный корень из отрицательного числа:
Или логарифм отрицательного числа:
4. Заключение
Понятие «не число», выраженное в JavaScript с помощью NaN, полезно для представления ошибочных операций над числами. NaN не равно ни одному значению, даже самому себе. Рекомендуемый способ проверить, содержит ли переменная NaN — использовать Number.isNaN(value).
Преобразование числовых строк в числа, в случае неудачи может дать NaN. Рекомендуется проверять, не возвращают ли parseInt(), parseFloat() или Number() NaN.
Если undefined или NaN используются в качестве операнда в арифметических операциях, это обычно приводит к NaN. Правильная обработка undefined (предоставление значений по умолчанию для отсутствующих свойств) является рекомендованным подходом для предотвращения этой ситуации.
Неопределенные формы или недопустимые аргументы для математических функций также приводят получению NaN. Но это случается редко. Вот мой практический совет: «Получили NaN? Ищите undefined!»
Автор: Dmitri Pavlutin
Редакция: Команда webformyself.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Источник