Why does `isFinite(null) === true`?

Why does `isFinite(null) === true`?

本文关键字:true does isFinite Why null      更新时间:2023-09-26

以下是我觉得有意义的例子。

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's 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,为什么?这还有什么影响?

ECMAScript规范(5.1)将isFinite定义为:

isFinite(数字)

如果参数强制为NaN、+∞或−∞,则返回false,否则返回true。

如果tonnumber (number)为NaN、+∞或−∞,则返回false。

否则返回true

换句话说,isFinite正在调用传入的任何东西的tonnumber,然后将其与pos/负无穷大或NaN进行比较。

在JavaScript中(注意使用!=代替更常见的!==,导致类型强制转换):

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

(如下面的注释所述,不需要someInput != NaN,因为NaN被定义为不等于所有东西,包括它自己)

现在,为什么null被转换为零(而不是undefined)?正如TylerH在评论中所说,null意味着存在一个值,但为空。它的数学表达式是0。undefined意味着那里没有值,所以当我们试图调用ToNumber时,我们得到NaN

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

然而,ECMAScript 6带来了一个不可转换的isFinite作为Number的属性。Douglas Crockford建议:http://wiki.ecmascript.org/doku.php?id=harmony:number.isfinite

From MDN:

全局isFinite()函数决定传递的值是否为一个有限的数。如果需要,首先将参数转换为a号码。

它被转换成一个数字…

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和underscore那样…

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

isFinite调用ToNumber的参数。所以

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

因为,如果你说

Number(null) === 0是有限的

参见To Number conversion

也就是说,对于参数类型null,结果是+0

isFinite将其参数类型转换为一个数字,如果它已经不是一个数字。本质上你有isFinite(Number(null))Number(null) === 0

除了null,您还会发现这些例子很有趣:

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

在JavaScript中发生隐式转换,当将数字与布尔值进行比较时,该转换尝试将bool转换为整数,或将字符串与数字进行比较时,将数字转换为字符串。如果您将任何数据类型视为数字,它将隐式转换为数字,因此上述所有情况都返回零,这是有限的。看到

如果你尝试Number(undefined),它会给你一个负的NaN,这将产生一个有限的1