На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ElcnU, ANDLL, fatalist
  
> isNaN, Number.isNaN , непонятки
    Здрасте :D
    непойму в чем проблема isNaN, которую описывают
    https://developer.mozilla.org/ru/docs/Web/J...NaN#Description
    там предлагется ей замена Number.isNaN, но я не понимаю в чем их разница, точнее разницу вижу, но не понимаю ее практического значения? :wacko:
    ExpandedWrap disabled
      isNaN('NaN');      // true
      isNaN(undefined);  // true
      isNaN({});         // true
      isNaN('blabla');   // true
       
      Number.isNaN('NaN');      // false
      Number.isNaN(undefined);  // false
      Number.isNaN({});         // false
      Number.isNaN('blabla');   // false

    и на что это влияет? ну isNaN(NaN) // true т.е. не число является не числом ясно, в другом случае Number.isNaN('NaN') - не число не является не числом и что?! :huh:
    Сообщение отредактировано: Cfon -
      А если вчитаться, то там написано:
      ExpandedWrap disabled
        // При использовании глобальной функции isNaN() это всё будет true
        ...
        Number.isNaN('blabla');   // false
         
        // Пример почему использование isNaN не всегда уместно
        isNaN("blabla")   // true: "blabla" преобразованно в число.
                          // При парсинге преобразуется в число при неудаче возвращает NaN
        Цитата simsergey @
        А если вчитаться, то там написано:
        ExpandedWrap disabled
          // При использовании глобальной функции isNaN() это всё будет true
          ...
          Number.isNaN('blabla');   // false
           
          // Пример почему использование isNaN не всегда уместно
          isNaN("blabla")   // true: "blabla" преобразованно в число.
                            // При парсинге преобразуется в число при неудаче возвращает NaN

        это я читал :D
        но не понимаю ее практического значения, ну вот например, там рекомендуют заменить
        ExpandedWrap disabled
          isNaN("blabla"); // true
        на
        ExpandedWrap disabled
          Number.isNaN(Number('blabla')); // true

        в обоих случаях true, что собственно и требуется, но в чем проблема то isNaN("blabla")? почему там пишут что она цитирую
        Цитата
        Функция isNaN() определяет является ли литерал или переменная не числовым значением (NaN) или нет. При работе с функцией необходимо проявлять осторожность так как она работает некорректно.

        :huh:

        я понимаю, что в глобальной isNaN значение автоматически преобразуется в число, а в Number.isNaN такое преобразование не происходит, это я все читал и понял, но я не понимаю, какие мне придут проблемы, если я буду юзать isNaN, вместо Number.isNaN? как в примере выше
        Сообщение отредактировано: Cfon -
          Я прочитав второй раз понял точно так же как и в первый :D
          Вообще, любая строка - это число (вспомни с++), любую строку можно преобразовать в число. Так ?
          Там написано, что isNaN() при парсинге строки может получить число, даже корректное, из строки "blabla", в то время как Number.isNaN() защищена от такого поведения.
          Поэтому они и рекомендуют ее использовать.

          А почему это принципиально, почему бы не последовать рекомендации? :)
            Цитата simsergey @
            Я прочитав второй раз понял точно так же как и в первый :D
            Вообще, любая строка - это число (вспомни с++), любую строку можно преобразовать в число. Так ?
            Там написано, что isNaN() при парсинге строки может получить число, даже корректное, из строки "blabla", в то время как Number.isNaN() защищена от такого поведения.
            Поэтому они и рекомендуют ее использовать.

            А почему это принципиально, почему бы не последовать рекомендации? :)

            смотри есть код
            ExpandedWrap disabled
              var s = '123';
               
              if (!isNaN(s)) {
                // todo something
              }

            какие проблемы у меня могу возникнуть? чем лучше след код?
            ExpandedWrap disabled
              var s = '123';
               
              if (!Number.isNaN(Number(s))) {
                // todo something
              }


            Добавлено
            Цитата simsergey @
            А почему это принципиально, почему бы не последовать рекомендации? :)

            потому что когда я чего то не понимаю, то не могу тупо следовать! :D

            Цитата simsergey @
            Там написано, что isNaN() при парсинге строки может получить число, даже корректное, из строки "blabla", в то время как Number.isNaN() защищена от такого поведения.
            Поэтому они и рекомендуют ее использовать.

            чего чего? как это получить из 'blabla' число? какое число? :huh:
            нифига ты не понял! :D
            Сообщение отредактировано: Cfon -
              Цитата Cfon @
              нифига ты не понял!
              Убедил. Давай еще раз почитаем:
              Цитата
              Метод Number.isNaN() определяет, является ли переданное значение NaN. Это более надёжная версия оригинальной глобальной функции isNaN().
              Цитата
              В отличие от глобальной функции isNaN(), Number.isNaN() не имеет проблемы принудительного преобразования параметра в число. Это значит, что в него безопасно передавать значения, которые обычно превращаются в NaN, но на самом деле NaN не являются. Также это значит, что метод возвращает true только для числовых значений, имеющих значение NaN.
              Цитата
              Путаница связана с тем, что "not a number" имеет определённое значение, описанное в стандарте IEEE-794 чисел с плавающей точкой. Функцию стоит воспринимать в качестве ответа на вопрос, "Является ли это значение корректным числом по стандарту IEEE-794?"

              И так:
              1) это более надёжная версия
              2) не имеет проблемы принудительного преобразования параметра в число
              3) знает разницу между истинным NaN, определенным в IEEE 754 (почему-то написано IEEE 794 :scratch: ).

              Можно затестить разницу, передав в isNaN() число (именно число), которое является NaN с точки зрения IEEE 754. :popcorn:
                Цитата simsergey @
                И так:
                1) это более надёжная версия
                2) не имеет проблемы принудительного преобразования параметра в число
                3) знает разницу между истинным NaN, определенным в IEEE 754 (почему-то написано IEEE 794 :scratch: ).

                Можно затестить разницу, передав в isNaN() число (именно число), которое является NaN с точки зрения IEEE 754. :popcorn:

                что ты мне голову морочишь? >:(

                все твои итак я понял! ты мне объясни, если конечно сам понял, какие проблемы isNaN есть в отличие от Number.isNaN?
                тока на примере! не надо мне перечислять, то что написано в MDN!

                вот к примеру я пишу функцию проверки некого формата, пускай это будет формат телефоного номера:
                ExpandedWrap disabled
                  // формат например такой: 123-4567
                  function validate(phone){
                    var first = phone.substring(0,3);
                    var second = phone.substring(phone.length,4);
                   
                    // тут проверяю что номер не содержит не числовые символы
                    if (isNaN(first) || isNaN(second)) {
                      return false;
                    }
                   
                    // еще какие то проверки
                    ....
                   
                    return true;
                  }
                   
                  validate('123-4567'); // true
                  validate('12a-4567'); // false


                код приведен чисто для примера и не является законченым примером валидации.
                объясни мне что тут не так с isNaN и зачем мне юзать Number.isNaN? :wall:
                Сообщение отредактировано: Cfon -
                  Цитата Cfon @
                  там предлагется ей замена Number.isNaN

                  С чего ты это решил? Там просто поясняется, что isNaN трактует понятие NaN не в узком смысле, как специальное числовое значение по стандарту IEEE, а в более широком - она возвращает true также и для не числовых аргументов, которые не могут быть представлены в числовом виде функцией ToNumber(). А критикуют ее за то, что она и на широкий смысл "Not A Number" не тянет, т.к. из-за особенностей ToNumber(), некие явно не числовые значения, такие как пустая строка или строка из одних пробелов, преобразуются в число 0, а не в NaN.
                  Поэтому речь ни о какой "замене" не идет - просто поясняется, что для отлова специального числового значения NaN по стандарту IEEE лучше использовать Number.isNaN. Ну а в широком смысле, для проверки возможности преобразования аргумента в число можно использовать isNaN (с учетом некоторых особенностей, типа пустой строки и т.п.).

                  Соотв-но замена isNaN(s) на Number.isNaN(Number(s))) не имеет смысла. Точнее может иметь смысл только в том случае, если явное преобразование Number(s) работает более корректно, чем встроенное в isNan.
                    Цитата leo @
                    С чего ты это решил? Там просто поясняется, что isNaN трактует понятие NaN не в узком смысле, как специальное числовое значение по стандарту IEEE, а в более широком - она возвращает true также и для не числовых аргументов, которые не могут быть представлены в числовом виде функцией ToNumber(). А критикуют ее за то, что она и на широкий смысл "Not A Number" не тянет, т.к. из-за особенностей ToNumber(), некие явно не числовые значения, такие как пустая строка или строка из одних пробелов, преобразуются в число 0, а не в NaN.
                    Поэтому речь ни о какой "замене" не идет - просто поясняется, что для отлова специального числового значения NaN по стандарту IEEE лучше использовать Number.isNaN. Ну а в широком смысле, для проверки возможности преобразования аргумента в число можно использовать isNaN (с учетом некоторых особенностей, типа пустой строки и т.п.).

                    Соотв-но замена isNaN(s) на Number.isNaN(Number(s))) не имеет смысла. Точнее может иметь смысл только в том случае, если явное преобразование Number(s) работает более корректно, чем встроенное в isNan.

                    с чего я решил? с того что там написано! >:(
                    ты читал что там ваще написано? мля народ не тупите! :wall:
                    Цитата
                    Функция isNaN() определяет является ли литерал или переменная не числовым значением (NaN) или нет. При работе с функцией необходимо проявлять осторожность так как она работает некорректно.

                    читай по слогам работает не-кор-рек-тно :D так что имелось ввиду под не корректно? на примере показать можете? или так и будете цитировать из MDN??? :wall:
                    Сообщение отредактировано: Cfon -
                      Цитата Cfon @
                      на примере показать можете?
                      Я на скрипте не пишу, поправь если что..
                      ExpandedWrap disabled
                        function validate1(){
                          var first = Math.sqrt(-1);
                          var second = 9007199254740990;
                          var res1;
                          var res2;
                          var res3;
                          var res4;
                         
                          res1 = Number.isNaN(first);
                          res2 = isNaN(first);
                         
                          res3 = Number.isNaN(second);
                          res4 = isNaN(second);
                         
                          return ((res1 == res2) == (res3 == res4));
                        }


                      Math.sqrt(-1) и 9007199254740990 оба NaN. Вот давай сравним результаты от двух функций.
                        Цитата Cfon @
                        читай по слогам работает не-кор-рек-тно
                        так что имелось ввиду под не корректно? на примере показать можете?

                        Во-первых, "не-кор-рек-тно" - только с точки зрения русского переводчика\интертрепатора, т.к. в аглицком варианте говорится только об "interesting" и "confusing" правилах преобразования не числовых параметров.
                        Во-вторых, специально для :wall: дают ссылку на эти "interesting" примеры, когда пустая строка '' или строка пробелов ' ' дают isNan = false, а прочие 'blablabla' - true. Где тут логика? Если уж blablabla является "не числом" (в широком смысле), то и строка пробелов тоже должна быть "не числом". Понятно, что дело не в самой isNaN, а в общей функции преобразования строки в число, которая работает по этим "странным" правилам. Поэтому и замена isNaN на Number.isNaN(Number(s)) тут никак не поможет, если преобразование пустых и пробельных строк будет выполняться по тем же общим правилам.

                        Посему правильнее говорить не о корректности, а об особенностях поведения isNaN, которые просто нужно учитывать и при необходимости добавлять дополнительные условия проверки.
                        А Number.isNaN полезна только для проверки числовых аргументов\выражений на равенство специальному числовому значению NaN по стандарту IEEE. Об этом собс-но и говорится в статье - если вас интересует только реальный числовой NaN по стандарту, а не результат какого-то неявного преобразования, то используйте Number.isNaN, которая при любом не числовом аргументе возвращает false. Только и всего
                        Сообщение отредактировано: leo -
                          Цитата simsergey @
                          Я на скрипте не пишу, поправь если что..
                          ExpandedWrap disabled
                            function validate1(){
                              var first = Math.sqrt(-1);
                              var second = 9007199254740990;
                              var res1;
                              var res2;
                              var res3;
                              var res4;
                             
                              res1 = Number.isNaN(first);
                              res2 = isNaN(first);
                             
                              res3 = Number.isNaN(second);
                              res4 = isNaN(second);
                             
                              return ((res1 == res2) == (res3 == res4));
                            }


                          Math.sqrt(-1) и 9007199254740990 оба NaN. Вот давай сравним результаты от двух функций.

                          ну смотрю и что? в обоих случаях одинаковые значения
                          ExpandedWrap disabled
                            res1 = Number.isNaN(first); // true
                            res2 = isNaN(first);        // true
                             
                            res3 = Number.isNaN(second); // false
                            res4 = isNaN(second);        // false


                          Добавлено
                          Цитата leo @
                          Во-вторых, специально для :wall: дают ссылку на эти "interesting" примеры, когда пустая строка '' или строка пробелов ' ' дают isNan = false, а прочие 'blablabla' - true. Где тут логика? Если уж blablabla является "не числом" (в широком смысле), то и строка пробелов тоже должна быть "не числом". Понятно, что дело не в самой isNaN, а в общей функции преобразования строки в число, которая работает по этим "странным" правилам. Поэтому и замена isNaN на Number.isNaN(Number(s)) тут никак не поможет, если преобразование пустых и пробельных строк будет выполняться по тем же общим правилам.

                          а вот это уже близко к истине :)
                          спс думаю в моем случае это будет ошибкой :yes:
                          ExpandedWrap disabled
                            validate('12 -4567'); //true

                          т.е. передавая вместо любой цифры пробел функция вычисляет не правильно и возвращает истину.
                          думаю в моем случае именно неправильная интерпретация пробела является ошибкой.
                          Сообщение отредактировано: Cfon -
                            Цитата Cfon @
                            думаю в моем случае именно неправильная интерпретация пробела является ошибкой.

                            И не только пробела, т.к. если тебе требуются только целые числа без знака, то к ошибке будет приводить и наличие знака +/- в начале числа, наличие десятичной точки или аглицкой буквы e/E в середине, а также 0x/0o/0b в начале, т.к. для isNan() и Number() это могут быть валидные числа.

                            А для твоей задачки с телефонным номером можно обойтись и без isNaN. Просто преобразуем строку в целое число через parseInt, затем полученное число снова переводим в строку (в десятичном виде) и сравниваем ее с исходным значением.
                            ExpandedWrap disabled
                              var n = parseInt(s);
                              return (n.toString() === s && n >= 0);
                            Сообщение отредактировано: leo -
                              Цитата leo @
                              И не только пробела, т.к. если тебе требуются только целые числа без знака, то к ошибке будет приводить и наличие знака +/- в начале числа, наличие десятичной точки или аглицкой буквы e/E в середине, а также 0x/0o/0b в начале, т.к. для isNan() и Number() это могут быть валидные числа.

                              да все верно :yes:

                              Цитата leo @
                              А для твоей задачки с телефонным номером можно обойтись и без isNaN. Просто преобразуем строку в целое число через parseInt, затем полученное число снова переводим в строку (в десятичном виде) и сравниваем ее с исходным значением.
                              ExpandedWrap disabled
                                var n = parseInt(s);
                                return (n.toString() === s && n >= 0);

                              ну это просто для примера я приводил, чтобы понять какие грабли могут быть при использовании isNaN :)
                              а вообще проще в данном случае юзать регулярки :)
                              ExpandedWrap disabled
                                function validate(phone){
                                  return phone.match(/^\d{3}-\d{4}$/);
                                }
                              Сообщение отредактировано: Cfon -
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0588 ]   [ 15 queries used ]   [ Generated: 16.04.24, 11:36 GMT ]