Подтвердить что ты не робот

Почему `isFinite (null) === true`?

Ниже приводятся примеры, которые имеют смысл для меня.

isFinite(5) // true - makes sense to me, it is a number and it is finite
  typeof 5 // "number"
isFinite(Infinity) // false - makes sense for logical reasons
  typeof Infinity // "number"
isFinite(document) // false - makes sense as well, it not even a number
  typeof document // "object"

Ниже я смущаюсь.

isFinite(null) // true - Wait what? Other non-number objects returned false. I see no reason?
  typeof null // "object"

Я просто не вижу причин для этого. То, что я хотел бы, это самый низкий уровень ответа. Я думаю, что null преобразуется в 0, почему? Какие еще воздействия это имеет?

4b9b3361

Ответ 1

Спецификация ECMAScript (5.1) определяет isFinite как таковой:

isFinite (число)

Возвращает false, если аргумент принуждает к NaN, + ∞ или -∞ и в противном случае возвращает true.

Если ToNumber (число) - NaN, + ∞ или -∞, верните false.

В противном случае верните true.

Другими словами, isFinite вызывает ToNumber о том, что передавалось, а затем сравнивая его с любой константой pos/neg или NaN.

В JavaScript (обратите внимание на использование != вместо более общего !==, вызывающего тип cast):

function isFinite(someInput) {
  return !isNaN(someInput) &&
    someInput != Number.POSITIVE_INFINITY &&
    someInput != Number.NEGATIVE_INFINITY;
}

(Как отмечено в ниже комментарии, someInput != NaN не требуется, поскольку NaN определяется как не эквивалентный всем, включая сам.)

Теперь, почему null преобразован в ноль (в отличие от undefined)? Как TylerH говорит в комментариях, null означает, что значение существует, но пусто. Математическое представление этого значения равно 0. undefined означает, что там нет значения, поэтому мы получаем NaN при попытке называть ToNumber на нем.

http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.5

Тем не менее, ECMAScript 6 несет неконвертирующее isFinite как свойство Number. Дуглас Крокфорд предложил это здесь: http://wiki.ecmascript.org/doku.php?id=harmony:number.isfinite

Ответ 2

Из MDN:

Глобальная функция isFinite() определяет, является ли переданное значение конечное число. При необходимости параметр сначала преобразуется в число.

Итак, он преобразуется в число...

isFinite(null)
isFinite(+null) //convert to a number
isFinite(0) // true because +null or Number(null) = 0

Спектр говорит, что глобальный метод isFinite() будет принудительно преобразовывать параметр в число.

Однако вы могли использовать (на свой страх и риск) спецификацию EcmaScript 6 Number.isFinite(), которая не выполняет это преобразование.

Number.isFinite(null) // false

Или, как lodash и подчеркивание, сделайте это...

var _.isFinite = function(obj) {
  return isFinite(obj) && !isNaN(parseFloat(obj));
};

Ответ 3

isFinite вызывает ToNumber свой аргумент. Так

> Number(null)
0
> Number(document)
NaN
> isFinite(0)
true
> isFinite(NaN)
false

> isFinite(null)
true
> isFinite(document)
false

Ответ 4

Потому что, если вы скажете

Number(null) === 0, который конечен

См. Конверсии чисел

Что говорит, что для типа аргумента null результат +0

Ответ 5

isFinite выводит аргумент в число, если оно уже не является числом. По существу у вас есть isFinite(Number(null)) и Number(null) === 0. Которое конечно.

Ответ 6

Помимо null, вы также найдете эти примеры:

alert(isFinite(' '));  //true
alert(isFinite(''));  //true
alert(isFinite(null));  //true
alert(isFinite(!undefined));  //true

В явном преобразовании JavaScript происходит. Это преобразование пытается преобразовать bool в integer при сравнении чисел с логическим значением или числом в строку при сравнении строки с числами. Если вы обрабатываете любой тип данных как число, он неявно преобразуется в число, поэтому все вышеприведенные случаи возвращают нулевой конечный результат. См. здесь

Если вы попробуете Number(undefined), он даст вам NaN при отрицании, это приведет к 1 конечному.