2014-03-18 43 views
29

以下是对我有意义的例子。为什么`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'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,为什么?这有什么其他影响?

+4

可能的重复[为什么isFinite(undefined)!= isFinite(null)?](http://stackoverflow.com/questions/19254205/why-is-isfiniteundefined-isfinitenull) – adeneo

+12

低级响应:在数学(因此在JavaScript中表面上),当某些值为空值时,它有一个空值或零值。零是有限数字。因此,null是有限的。除非你能成为第一个找到无穷的倒数的人,否则我怀疑这会永远改变。 – TylerH

+0

@TylerH这是一个很好的方式来说出它。谢谢。 – user1596138

回答

46

ECMAScript的规范(5.1)定义isFinite充当这样的:

isFinite的(数量)

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

如果ToNumber(number)是NaN,+∞或-∞,则返回false。

否则,返回true。

换句话说,isFinite呼吁任何真实传递在ToNumber,然后比较它要么正/负无穷大或NaN。

在JavaScript(请注意使用的!=而不是更常用的!==,造成类型转换):

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

(如the comments below指出,不需要someInput != NaN,如NaN被定义为不相当于一切,包括它本身。)

现在,为什么null转换为零(而不是undefined)?由于TylerH says在评论中,null意味着存在一个值,但是是空的。这个的数学表示是0。undefined表示这里没有值,因此我们在尝试调用ToNumber时得到NaN

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

+0

Crockford's * isFinite *是不一致的想法:'Crockford_isFinite(Number(null))=== true'。 ;-) – RobG

+7

为什么要麻烦'someInput!= NaN'? JavaScript中的所有值都被定义为不等于NaN,包括NaN。 –

+2

@ChrisHayes明确地像标准所说的。效率不高,但更清楚。 – SomeKittens

12

从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)); 
}; 
+0

为什么它是“需要”吗?我可以看到这是已经返回的内容,我在问为什么:P – user1596138

+1

@Jhawins:因为这就是规范所说的。其他任何事情都是意见。 –

+0

我很乐意接受你的回答,但看看@SomeKittens在下面做了些什么......你在1分钟内击败了他,但这很聪明。尽管如此,仍然只有1分钟,直到我可以接受:P – user1596138

4

isFinite typecasts它是一个数字的参数,如果它不是一个数字。基本上你有isFinite(Number(null))Number(null) === 0。这是有限的。

11

isFinite其调用ToNumber。所以

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

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

因为,如果你说

Number(null) === 0是有限

To Number Conversions

它说的是,对于参数类型null结果是+0

3

除了null,你找到这些examples有趣太:

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

在JavaScript隐式转换发生,这种转换尝试转换布尔与布尔比较时数字或数字串与数字比较字符串时为整数。如果将任何数据类型视为数字,则它将隐式转换为数字,以便以上所有情况都返回有限的零。 See Here

如果您尝试Number(undefined)它会给你一个NaN否定这将产生一个有限的1。

+1

也'alert(isFinite(true)); // true“被视为1 –

相关问题