Конвертировать NaN в 0 в JavaScript

238

Есть ли способ преобразовать значения NaN в 0 без оператора if:

if (isNaN(a)) a = 0;

Очень раздражает каждый раз проверять мои переменные.

Тамас Пап
источник
4
Разве вы не можете просто превратить это в функцию?
the_drow
Это всего лишь 20 символов, в чем проблема?
Расти Фаусак
1
function noNaN( n ) { return isNaN( n ) ? 0 : n; }а потом простоnoNaN( a )
Шиме Видас
1
@ rfausak Вы обычно не хотите повторяться (см. СУХОЙ ). Если определенная функциональность требуется несколько раз, предпочтительной является выделенная функция.
Шиме Видас

Ответы:

575

Ты можешь сделать это:

a = a || 0

... который преобразует из любого значения "фальси" в 0.

Значения "фальси":

  • false
  • null
  • undefined
  • 0
  • "" ( пустая строка )
  • NaN (Не число)

Или это, если вы предпочитаете:

a = a ? a : 0;

... который будет иметь тот же эффект, что и выше.


Если целью было проверить больше, чем просто NaN, то вы можете сделать то же самое, но сначала выполнить преобразование toNumber .

a = +a || 0

Это использует унарный оператор +, чтобы попытаться преобразовать aв число. Это дает дополнительное преимущество преобразования таких вещей, как числовые строки '123'в число.

Единственной неожиданностью может быть случай, когда кто-то передает массив, который может быть успешно преобразован в число:

+['123']  // 123

Здесь у нас есть массив, состоящий из одного члена, представляющего собой числовую строку. Он будет успешно преобразован в число.

user113716
источник
Идея превратить проверку в функцию хороша, но она более элегантна.
Тамас Пап
1
@ Бакудан: Хороший вопрос. Я думал, что OP касается только конкретной NaNценности. Это не будет работать в качестве теста для всех не числовых значений. Хотя мы могли бы сначала попытаться преобразовать toNumber. Я обновлю.
user113716
... ах, это из-за названия "Конвертировать NaN в 0" . Во всяком случае, покрыты оба пути.
user113716
2
Спасибо друг, выбрал и изменил немного это для себя a = a * 1 || 0
Кто-нибудь
Потрясающие. Спасибо
Апит Джон Исмаил
32

Использование двойной тильды (двойного побитового НЕ) ~~- делает некоторые интересные вещи в JavaScript. Например, вы можете использовать его вместо Math.floorили даже в качестве альтернативы parseInt("123", 10)! Это много обсуждалось в Интернете, поэтому я не буду вдаваться в то, почему это работает, но если вам интересно: что такое оператор «двойная тильда» (~~) в JavaScript?

Мы можем использовать это свойство двойной тильды для преобразования NaNв число, и, к счастью, это число равно нулю!

console.log(~~NaN); // 0

WickyNilliams
источник
1
Спасибо, я не знал об этом ~~вообще, я просто использовал его наряду с parseFloat()примерно так: ~~parseFloat($variable);. Очень аккуратно :) +1
Ренс Тиллманн
23

Напишите свой собственный метод и используйте его везде, где вам нужно числовое значение:

function getNum(val) {
   if (isNaN(val)) {
     return 0;
   }
   return val;
}
Сакет
источник
1
Если я уйду, nullто это не даст мне ожидаемого результата 0. Больше на мой
Андрей Базанов
2
В дополнение к моему комментарию, приведенному выше, я в конечном итоге использовал Number(val)вместо этого, поскольку он возвращает, 0когда он все равно не может понять это.
Андрей Базанов
4

Что-то более простое и эффективное для чего-либо:

function getNum(val) {
   val = +val || 0
   return val;
}

... который преобразует из любого значения "фальси" в 0.

Значения "фальси":

  • false
  • null
  • undefined
  • 0
  • "" ( пустая строка )
  • NaN (Не число)
Woold
источник
1
Интересный! Просто интересно, как он реагирует, когда значение val может быть отрицательным. Насколько я проверял, в этом нет ничего плохого, но на всякий случай ...
Лучано
2

Вместо того, чтобы ставить его в тупик, чтобы продолжить, почему бы не сделать резервную копию и не задуматься, почему вы столкнулись с NaN?

Если какой-либо из числовых входов для операции является NaN, выход также будет NaN. Именно так работает текущий стандарт IEEE с плавающей точкой (это не только Javascript). Это поведение по уважительной причине : основная цель состоит в том, чтобы удержать вас от использования фиктивного результата, даже не осознавая его фиктивность.

Способ работы NaN заключается в том, что если что-то идет не так, как надо, в какой-то под-под-подоперации (создание NaN на этом более низком уровне), конечный результат также будет будет NaN, который вы сразу же признаете ошибочным, даже если ваш Логика обработки ошибок (возможно, throw / catch?) еще не завершена.

NaN как результат арифметического расчета всегда указывает на то, что что-то пошло не так в деталях арифметики. Это способ для компьютера сказать «отладка необходима здесь». Вместо того, чтобы найти какой-либо способ продолжить с каким-то числом, которое вряд ли когда-либо окажется правильным (действительно ли 0 соответствует вашему желанию?), Почему бы не найти проблему и устранить ее.

Распространенной проблемой в Javascript является то, что оба parseInt(...)и parseFloat(...)будут возвращать NaN, если дан бессмысленный аргумент ( null, ''и т. Д.). Исправьте проблему на самом низком возможном уровне, а не на более высоком уровне. Тогда у результата общего вычисления есть хороший шанс иметь смысл, и вы не подставляете какое-то магическое число (0 или 1 или что-то еще) в качестве результата всего вычисления. (Трюк (parseInt (foo.value) || 0) работает только для сумм, а не для продуктов - для продуктов вы хотите, чтобы значение по умолчанию было 1, а не 0, но не если указанное значение действительно равно 0.)

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

function getFoobarFromUser(elementid) {
        var foobar = parseFloat(document.getElementById(elementid).innerHTML)
        if (isNaN(foobar)) foobar = 3.21;       // default value
        return(foobar.toFixed(2));
}
Чак Колларс
источник
2

Как насчет регулярного выражения ?

function getNum(str) {
  return /[-+]?[0-9]*\.?[0-9]+/.test(str)?parseFloat(str):0;
}

Код ниже будет игнорировать NaN, чтобы позволить вычисление правильно введенных чисел

mplungjan
источник
2

Методы, использующие isNaN, не работают, если вы пытаетесь использовать parseInt, например:

parseInt("abc"); // NaN
parseInt(""); // NaN
parseInt("14px"); // 14

Но во втором случае isNaN выдает false (т. Е. Нулевая строка является числом)

n="abc"; isNaN(n) ? 0 : parseInt(n); // 0
n=""; isNaN(n) ? 0: parseInt(n); // NaN
n="14px"; isNaN(n) ? 0 : parseInt(n); // 14

Таким образом, пустая строка считается действительным числом isNaN, но не parseInt. Проверено с Safari, Firefox и Chrome на OSX Mojave.

Дэвид Кроу
источник
1
Одно очевидное решение немного громоздко, проверять NaN после parseInt, а не раньше: isNaN (parseInt (n))? parseInt (n): 0; // дважды вызывает parseInt :(
Дэвид Кроу
1
этот комментарий должен быть (началом) вашего ответа!
frandroid
Более эффективное решение предполагает, что нулевая строка является единственной аномалией: n == "" || isNaN (n)? 0: parseInt (n); (но что, если есть другие строки?)
Дэвид Кроу
1
var i = [NaN, 1,2,3];

var j = i.map(i =>{ return isNaN(i) ? 0 : i});

console.log(j)

[0,1,2,3]

KARTHIKEYAN.A
источник
0

используя решение пользователя 113716, которое, кстати, прекрасно, чтобы избежать всех тех случаев, если я еще реализовал его таким образом, чтобы вычислить мое текстовое поле промежуточных итогов из единицы текстового поля и количества текстового поля.

В процессе записи не чисел в текстовых полях единиц и количеств их значения заменяются на ноль, поэтому при окончательном размещении пользовательских данных не будет никаких чисел.

     <script src="/common/tools/jquery-1.10.2.js"></script>
     <script src="/common/tools/jquery-ui.js"></script>

     <!----------------- link above 2 lines to your jquery files ------>





    <script type="text/javascript" >
    function calculate_subtotal(){

    $('#quantity').val((+$('#quantity').val() || 0));
    $('#unit').val((+$('#unit').val() || 0));

    var  calculated = $('#quantity').val() * $('#unit').val() ;
    $('#subtotal').val(calculated);


    }
    </script>


      <input type = "text" onChange ="calculate_subtotal();" id = "quantity"/>
      <input type = "text" onChange ="calculate_subtotal();" id = "unit"/>
      <input type = "text" id = "subtotal"/>
webzy
источник
0

Пожалуйста, попробуйте эту простую функцию

var NanValue = function (entry) {
    if(entry=="NaN") {
        return 0.00;
    } else {
        return entry;
    }
}
Subindas вечера
источник