Этот код в JS дает мне всплывающее окно с сообщением «Я думаю, что null - это число», что меня немного беспокоит. Что мне не хватает?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}
Я использую Firefox 3. Это ошибка браузера?
Другие тесты:
console.log(null == NaN); // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false
Значит, проблема не в точном сравнении с NaN?
Изменить: теперь на вопрос дан ответ, я очистил свой пост, чтобы получить лучшую версию для архива. Однако это делает некоторые комментарии и даже ответы немного непонятными. Не вините их авторов. Среди вещей, которые я изменил, было:
- Удалено примечание о том, что я изначально напортачил с заголовком, вернув его значение.
- Более ранние ответы показали, что я недостаточно четко указал, почему считаю такое поведение странным, поэтому я добавил примеры, которые проверяют строку и проводят сравнение вручную.
javascript
Ханно Фиц
источник
источник
Ответы:
Я полагаю, что код пытается спросить, "
x
числовой?" с конкретным случаем здесьx = null
. ДляisNaN()
ответа на этот вопрос можно использовать функцию , но семантически она относится именно к значениюNaN
. Из Википедии по запросуNaN
:В большинстве случаев мы думаем, что ответ на вопрос «является нулевым числом?» должно быть нет. Однако
isNaN(null) == false
семантически правильно, потому чтоnull
это не такNaN
.Вот алгоритмическое объяснение:
Функция
isNaN(x)
пытается преобразовать переданный параметр в число 1 (эквивалентNumber(x)
), а затем проверяет, равно ли значениеNaN
. Если параметр не может быть преобразован в число,Number(x)
вернетсяNaN
2 . Следовательно, если преобразование параметраx
в число дает результатNaN
, возвращается значение true; в противном случае возвращается false.Таким образом , в данном конкретном случае
x = null
,null
преобразуется в число 0, (попробуйте оценитьNumber(null)
и увидеть , что она возвращает 0,) иisNaN(0)
возвращает ложь. Строка, состоящая только из цифр, может быть преобразована в число, и isNaN также возвращает false. Строка (например'abcd'
), которая не может быть преобразована в число, приведетisNaN('abcd')
к возврату истины, особенно потому, чтоNumber('abcd')
возвращаетNaN
.В дополнение к этим очевидным граничным случаям есть стандартные числовые причины для возврата NaN, например 0/0.
Что касается кажущихся непоследовательными тестов на равенство, показанных в вопросе, поведение
NaN
задается таким образом, что любое сравнениеx == NaN
является ложным, независимо от другого операнда, включаяNaN
сам 1 .источник
NaN !== NaN
. Так что, я думаю, это не совсем правильно говорить,Number('abcd') == NaN
потому чтоNumber('abcd')
есть,NaN
но не равноNaN
. Обожаю JavaScript.Number('abcd')
это так,NaN
но подразумевал, что это проверяет истинность на равенство, но это не так. Я его отредактирую.isNaN
иNumber
предназначены для себя таким образом?null
чтобы0
только ( по крайней мере , в данном контексте) происходит в пределахisNaN()
функции, которая принуждает ее аргумент.Я сам столкнулся с этой проблемой.
Для меня лучший способ использовать isNaN - это так
isNaN(parseInt(myInt))
взяв пример физомы сверху,
(Я выровнял результат в соответствии с вводными данными, надеюсь, это облегчит чтение.)
Мне так кажется лучше.
источник
myInt
= "123d".parseInt
преобразует «123d» в 123, которое затем не проходитisNaN
проверку.isNaN(parseInt(str,10)) || isNaN(Number())
. btw - для меня, поскольку мне нужно запуститьparseInt
, чтобы использовать числовое значение строки, допустить, чтобы "123d" считалось действительным числом, это нормально. Однако я вижу необходимость обнаружить и этот сценарий.(Мой другой комментарий основан на практическом подходе. Вот теоретическая сторона.)
Я просмотрел стандарт ECMA 262 , который реализует Javascript. Их спецификация для isNan:
Раздел 9.3 определяет поведение
ToNumber
(которое является не вызываемой функцией, а скорее компонентом системы преобразования типов). Подводя итог таблице, можно сказать, что некоторые типы ввода могут давать NaN. Это типundefined
, типnumber
(но только значениеNaN
), любой объект, чье примитивное представление естьNaN
, и все,string
что не может быть проанализировано. Это листьяundefined
,NaN
,new Number(NaN)
, и большинство строк.Любой такой вход , который производит в
NaN
качестве выходного сигнала при передачеToNumber
будет производитьtrue
при скармливанииisNaN
. Посколькуnull
можно успешно преобразовать в число, он не производитtrue
.И вот почему.
источник
Это действительно беспокоит. Вот массив значений, которые я тестировал:
Он оценивает (в консоли Firebug) как:
Когда я звоню
x.map(isNaN)
(чтобы вызвать isNaN для каждого значения), я получаю:В заключение
isNaN
выглядит довольно бесполезным! ( Изменить : за исключением того, что isNaN определяется только для Number, и в этом случае он работает нормально - только с вводящим в заблуждение именем.)Между прочим, вот типы этих значений:
источник
Null не является NaN, как и строка не является NaN. isNaN () просто проверьте, действительно ли у вас есть объект NaN.
источник
Я не совсем уверен, когда дело доходит до JS, но я видел похожие вещи на других языках, и обычно это потому, что функция только проверяет, точно ли null равно NaN (т.е. null === NaN будет ложным). Другими словами, он не считает, что null на самом деле является числом, а скорее, что null не является NaN. Вероятно, это связано с тем, что оба они представлены в JS по-разному, поэтому они не будут точно равны, точно так же, как 9! == '9'.
источник
В ES5 он определен как
isNaN (number)
возвращает true, если аргумент приводится к NaN, а в противном случае возвращает false.И посмотрите таблицу преобразования ToNumber абстрактной операции . Так что внутри JS двигатель оценивать
ToNumber(Null)
это+0
, то в конечном итогеisNaN(null)
являетсяfalse
источник
Примечание:
Оператор == выполняет преобразование типов, а === - нет.
Сайт Дугласа Крокфорда , Yahoo! Евангелист JavaScript - отличный ресурс для подобных вещей.
источник