概述
整數(shù)和浮點(diǎn)數(shù)
JavaScript 內(nèi)部,所有數(shù)字都是以64位浮點(diǎn)數(shù)形式儲(chǔ)存蔑匣,即使整數(shù)也是如此。所以棕诵,1
與1.0
是相同的裁良,是同一個(gè)數(shù)。
1 === 1.0 // true
這就是說(shuō)年鸳,JavaScript 語(yǔ)言的底層根本沒(méi)有整數(shù)趴久,所有數(shù)字都是小數(shù)(64位浮點(diǎn)數(shù))丸相。容易造成混淆的是搔确,某些運(yùn)算只有整數(shù)才能完成,此時(shí) JavaScript 會(huì)自動(dòng)把64位浮點(diǎn)數(shù)灭忠,轉(zhuǎn)成32位整數(shù)膳算,然后再進(jìn)行運(yùn)算,參見《運(yùn)算符》一章的”位運(yùn)算“部分弛作。
由于浮點(diǎn)數(shù)不是精確的值涕蜂,所以涉及小數(shù)的比較和運(yùn)算要特別小心。
0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
數(shù)值精度
根據(jù)國(guó)際標(biāo)準(zhǔn) IEEE 754映琳,JavaScript 浮點(diǎn)數(shù)的64個(gè)二進(jìn)制位机隙,從最左邊開始蜘拉,是這樣組成的。
- 第1位:符號(hào)位有鹿,
0
表示正數(shù)旭旭,1
表示負(fù)數(shù) - 第2位到第12位(共11位):指數(shù)部分
- 第13位到第64位(共52位):小數(shù)部分(即有效數(shù)字)
符號(hào)位決定了一個(gè)數(shù)的正負(fù),指數(shù)部分決定了數(shù)值的大小葱跋,小數(shù)部分決定了數(shù)值的精度持寄。
指數(shù)部分一共有11個(gè)二進(jìn)制位,因此大小范圍就是0到2047娱俺。IEEE 754 規(guī)定稍味,如果指數(shù)部分的值在0到2047之間(不含兩個(gè)端點(diǎn)),那么有效數(shù)字的第一位默認(rèn)總是1荠卷,不保存在64位浮點(diǎn)數(shù)之中模庐。也就是說(shuō),有效數(shù)字這時(shí)總是1.xx...xx
的形式油宜,其中xx..xx
的部分保存在64位浮點(diǎn)數(shù)之中赖欣,最長(zhǎng)可能為52位。因此验庙,JavaScript 提供的有效數(shù)字最長(zhǎng)為53個(gè)二進(jìn)制位顶吮。
(-1)^符號(hào)位 * 1.xx...xx * 2^指數(shù)部分
上面公式是正常情況下(指數(shù)部分在0到2047之間),一個(gè)數(shù)在 JavaScript 內(nèi)部實(shí)際的表示形式粪薛。
精度最多只能到53個(gè)二進(jìn)制位悴了,這意味著,絕對(duì)值小于等于2的53次方的整數(shù)违寿,即-253到253湃交,都可以精確表示。
Math.pow(2, 53)
// 9007199254740992
Math.pow(2, 53) + 1
// 9007199254740992
Math.pow(2, 53) + 2
// 9007199254740994
Math.pow(2, 53) + 3
// 9007199254740996
Math.pow(2, 53) + 4
// 9007199254740996
上面代碼中藤巢,大于2的53次方以后搞莺,整數(shù)運(yùn)算的結(jié)果開始出現(xiàn)錯(cuò)誤。所以掂咒,大于2的53次方的數(shù)值才沧,都無(wú)法保持精度。由于2的53次方是一個(gè)16位的十進(jìn)制數(shù)值绍刮,所以簡(jiǎn)單的法則就是温圆,JavaScript 對(duì)15位的十進(jìn)制數(shù)都可以精確處理。
Math.pow(2, 53)
// 9007199254740992
// 多出的三個(gè)有效數(shù)字孩革,將無(wú)法保存
9007199254740992111
// 9007199254740992000
上面示例表明岁歉,大于2的53次方以后,多出來(lái)的有效數(shù)字(最后三位的111
)都會(huì)無(wú)法保存膝蜈,變成0锅移。
數(shù)值范圍
根據(jù)標(biāo)準(zhǔn)熔掺,64位浮點(diǎn)數(shù)的指數(shù)部分的長(zhǎng)度是11個(gè)二進(jìn)制位,意味著指數(shù)部分的最大值是2047(2的11次方減1)非剃。也就是說(shuō)瞬女,64位浮點(diǎn)數(shù)的指數(shù)部分的值最大為2047,分出一半表示負(fù)數(shù)努潘,則 JavaScript 能夠表示的數(shù)值范圍為21024到2-1023(開區(qū)間)诽偷,超出這個(gè)范圍的數(shù)無(wú)法表示。
如果一個(gè)數(shù)大于等于2的1024次方疯坤,那么就會(huì)發(fā)生“正向溢出”报慕,即 JavaScript 無(wú)法表示這么大的數(shù),這時(shí)就會(huì)返回Infinity
压怠。
Math.pow(2, 1024) // Infinity
如果一個(gè)數(shù)小于等于2的-1075次方(指數(shù)部分最小值-1023眠冈,再加上小數(shù)部分的52位),那么就會(huì)發(fā)生為“負(fù)向溢出”菌瘫,即 JavaScript 無(wú)法表示這么小的數(shù)蜗顽,這時(shí)會(huì)直接返回0。
Math.pow(2, -1075) // 0
下面是一個(gè)實(shí)際的例子雨让。
var x = 0.5;
for(var i = 0; i < 25; i++) {
x = x * x;
}
x // 0
上面代碼中雇盖,對(duì)0.5
連續(xù)做25次平方,由于最后結(jié)果太接近0栖忠,超出了可表示的范圍崔挖,JavaScript 就直接將其轉(zhuǎn)為0。
JavaScript 提供Number
對(duì)象的MAX_VALUE
和MIN_VALUE
屬性庵寞,返回可以表示的具體的最大值和最小值狸相。
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
數(shù)值的表示法
JavaScript 的數(shù)值有多種表示方法,可以用字面形式直接表示捐川,比如35
(十進(jìn)制)和0xFF
(十六進(jìn)制)脓鹃。
數(shù)值也可以采用科學(xué)計(jì)數(shù)法表示,下面是幾個(gè)科學(xué)計(jì)數(shù)法的例子古沥。
123e3 // 123000
123e-3 // 0.123
-3.1E+12
.1e-23
科學(xué)計(jì)數(shù)法允許字母e
或E
的后面瘸右,跟著一個(gè)整數(shù),表示這個(gè)數(shù)值的指數(shù)部分渐白。
以下兩種情況尊浓,JavaScript 會(huì)自動(dòng)將數(shù)值轉(zhuǎn)為科學(xué)計(jì)數(shù)法表示,其他情況都采用字面形式直接表示纯衍。
(1)小數(shù)點(diǎn)前的數(shù)字多于21位。
1234567890123456789012
// 1.2345678901234568e+21
123456789012345678901
// 123456789012345680000
(2)小數(shù)點(diǎn)后的零多于5個(gè)苗胀。
// 小數(shù)點(diǎn)后緊跟5個(gè)以上的零襟诸,
// 就自動(dòng)轉(zhuǎn)為科學(xué)計(jì)數(shù)法
0.0000003 // 3e-7
// 否則瓦堵,就保持原來(lái)的字面形式
0.000003 // 0.000003
數(shù)值的進(jìn)制
使用字面量(literal)直接表示一個(gè)數(shù)值時(shí),JavaScript 對(duì)整數(shù)提供四種進(jìn)制的表示方法:十進(jìn)制歌亲、十六進(jìn)制菇用、八進(jìn)制、二進(jìn)制陷揪。
- 十進(jìn)制:沒(méi)有前導(dǎo)0的數(shù)值惋鸥。
- 八進(jìn)制:有前綴
0o
或0O
的數(shù)值,或者有前導(dǎo)0悍缠、且只用到0-7的八個(gè)阿拉伯?dāng)?shù)字的數(shù)值卦绣。 - 十六進(jìn)制:有前綴
0x
或0X
的數(shù)值。 - 二進(jìn)制:有前綴
0b
或0B
的數(shù)值飞蚓。
默認(rèn)情況下滤港,JavaScript 內(nèi)部會(huì)自動(dòng)將八進(jìn)制、十六進(jìn)制趴拧、二進(jìn)制轉(zhuǎn)為十進(jìn)制溅漾。下面是一些例子。
0xff // 255
0o377 // 255
0b11 // 3
如果八進(jìn)制著榴、十六進(jìn)制添履、二進(jìn)制的數(shù)值里面,出現(xiàn)不屬于該進(jìn)制的數(shù)字脑又,就會(huì)報(bào)錯(cuò)缝龄。
0xzz // 報(bào)錯(cuò)
0o88 // 報(bào)錯(cuò)
0b22 // 報(bào)錯(cuò)
上面代碼中,十六進(jìn)制出現(xiàn)了字母z
挂谍、八進(jìn)制出現(xiàn)數(shù)字8
叔壤、二進(jìn)制出現(xiàn)數(shù)字2
,因此報(bào)錯(cuò)口叙。
通常來(lái)說(shuō)炼绘,有前導(dǎo)0的數(shù)值會(huì)被視為八進(jìn)制,但是如果前導(dǎo)0后面有數(shù)字8
和9
妄田,則該數(shù)值被視為十進(jìn)制俺亮。
0888 // 888
0777 // 511
前導(dǎo)0表示八進(jìn)制,處理時(shí)很容易造成混亂疟呐。ES5 的嚴(yán)格模式和 ES6脚曾,已經(jīng)廢除了這種表示法,但是瀏覽器為了兼容以前的代碼启具,目前還繼續(xù)支持這種表示法本讥。
特殊數(shù)值
JavaScript 提供了幾個(gè)特殊的數(shù)值。
正零和負(fù)零
前面說(shuō)過(guò),JavaScript 的64位浮點(diǎn)數(shù)之中拷沸,有一個(gè)二進(jìn)制位是符號(hào)位色查。這意味著,任何一個(gè)數(shù)都有一個(gè)對(duì)應(yīng)的負(fù)值撞芍,就連0
也不例外秧了。
JavaScript 內(nèi)部實(shí)際上存在2個(gè)0
:一個(gè)是+0
,一個(gè)是-0
序无,區(qū)別就是64位浮點(diǎn)數(shù)表示法的符號(hào)位不同验毡。它們是等價(jià)的。
-0 === +0 // true
0 === -0 // true
0 === +0 // true
幾乎所有場(chǎng)合帝嗡,正零和負(fù)零都會(huì)被當(dāng)作正常的0
晶通。
+0 // 0
-0 // 0
(-0).toString() // '0'
(+0).toString() // '0'
唯一有區(qū)別的場(chǎng)合是,+0
或-0
當(dāng)作分母丈探,返回的值是不相等的录择。
(1 / +0) === (1 / -0) // false
上面的代碼之所以出現(xiàn)這樣結(jié)果,是因?yàn)槌哉愕玫?code>+Infinity碗降,除以負(fù)零得到-Infinity
隘竭,這兩者是不相等的(關(guān)于Infinity
詳見下文)。
NaN
(1)含義
NaN
是 JavaScript 的特殊值讼渊,表示“非數(shù)字”(Not a Number)动看,主要出現(xiàn)在將字符串解析成數(shù)字出錯(cuò)的場(chǎng)合。
5 - 'x' // NaN
上面代碼運(yùn)行時(shí)爪幻,會(huì)自動(dòng)將字符串x
轉(zhuǎn)為數(shù)值菱皆,但是由于x
不是數(shù)值,所以最后得到結(jié)果為NaN
挨稿,表示它是“非數(shù)字”(NaN
)仇轻。
另外,一些數(shù)學(xué)函數(shù)的運(yùn)算結(jié)果會(huì)出現(xiàn)NaN
奶甘。
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
0
除以0
也會(huì)得到NaN
篷店。
0 / 0 // NaN
需要注意的是,NaN
不是獨(dú)立的數(shù)據(jù)類型臭家,而是一個(gè)特殊數(shù)值疲陕,它的數(shù)據(jù)類型依然屬于Number
,使用typeof
運(yùn)算符可以看得很清楚钉赁。
typeof NaN // 'number'
(2)運(yùn)算規(guī)則
NaN
不等于任何值蹄殃,包括它本身。
NaN === NaN // false
數(shù)組的indexOf
方法內(nèi)部使用的是嚴(yán)格相等運(yùn)算符你踩,所以該方法對(duì)NaN
不成立诅岩。
[NaN].indexOf(NaN) // -1
NaN
在布爾運(yùn)算時(shí)被當(dāng)作false
讳苦。
Boolean(NaN) // false
NaN
與任何數(shù)(包括它自己)的運(yùn)算,得到的都是NaN
按厘。
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
Infinity
(1)含義
Infinity
表示“無(wú)窮”医吊,用來(lái)表示兩種場(chǎng)景钱慢。一種是一個(gè)正的數(shù)值太大逮京,或一個(gè)負(fù)的數(shù)值太小,無(wú)法表示束莫;另一種是非0數(shù)值除以0懒棉,得到Infinity
。
// 場(chǎng)景一
Math.pow(2, 1024)
// Infinity
// 場(chǎng)景二
0 / 0 // NaN
1 / 0 // Infinity
上面代碼中览绿,第一個(gè)場(chǎng)景是一個(gè)表達(dá)式的計(jì)算結(jié)果太大策严,超出了能夠表示的范圍,因此返回Infinity
饿敲。第二個(gè)場(chǎng)景是0
除以0
會(huì)得到NaN
妻导,而非0數(shù)值除以0
,會(huì)返回Infinity
怀各。
Infinity
有正負(fù)之分倔韭,Infinity
表示正的無(wú)窮,-Infinity
表示負(fù)的無(wú)窮瓢对。
Infinity === -Infinity // false
1 / -0 // -Infinity
-1 / -0 // Infinity
上面代碼中寿酌,非零正數(shù)除以-0
,會(huì)得到-Infinity
硕蛹,負(fù)數(shù)除以-0
醇疼,會(huì)得到Infinity
。
由于數(shù)值正向溢出(overflow)法焰、負(fù)向溢出(underflow)和被0
除秧荆,JavaScript 都不報(bào)錯(cuò),而是返回Infinity
埃仪,所以單純的數(shù)學(xué)運(yùn)算幾乎沒(méi)有可能拋出錯(cuò)誤乙濒。
Infinity
大于一切數(shù)值(除了NaN
),-Infinity
小于一切數(shù)值(除了NaN
)贵试。
Infinity > 1000 // true
-Infinity < -1000 // true
Infinity
與NaN
比較琉兜,總是返回false
。
Infinity > NaN // false
-Infinity > NaN // false
Infinity < NaN // false
-Infinity < NaN // false
(2)運(yùn)算規(guī)則
Infinity
的四則運(yùn)算毙玻,符合無(wú)窮的數(shù)學(xué)計(jì)算規(guī)則豌蟋。
5 * Infinity // Infinity
5 - Infinity // -Infinity
Infinity / 5 // Infinity
5 / Infinity // 0
0乘以Infinity
,返回NaN
桑滩;0除以Infinity
梧疲,返回0
允睹;Infinity
除以0,返回Infinity
幌氮。
0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity
Infinity
加上或乘以Infinity
缭受,返回的還是Infinity
。
Infinity + Infinity // Infinity
Infinity * Infinity // Infinity
Infinity
減去或除以Infinity
该互,得到NaN
米者。
Infinity - Infinity // NaN
Infinity / Infinity // NaN
Infinity
與null
計(jì)算時(shí),null
會(huì)轉(zhuǎn)成0宇智,等同于與0
的計(jì)算蔓搞。
null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity
Infinity
與undefined
計(jì)算,返回的都是NaN
随橘。
undefined + Infinity // NaN
undefined - Infinity // NaN
undefined * Infinity // NaN
undefined / Infinity // NaN
Infinity / undefined // NaN
與數(shù)值相關(guān)的全局方法
parseInt()
(1)基本用法
parseInt
方法用于將字符串轉(zhuǎn)為整數(shù)喂分。
parseInt('123') // 123
如果字符串頭部有空格,空格會(huì)被自動(dòng)去除机蔗。
parseInt(' 81') // 81
如果parseInt
的參數(shù)不是字符串糯彬,則會(huì)先轉(zhuǎn)為字符串再轉(zhuǎn)換纵竖。
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
字符串轉(zhuǎn)為整數(shù)的時(shí)候慨蛙,是一個(gè)個(gè)字符依次轉(zhuǎn)換瘪贱,如果遇到不能轉(zhuǎn)為數(shù)字的字符,就不再進(jìn)行下去酿愧,返回已經(jīng)轉(zhuǎn)好的部分沥潭。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
上面代碼中,parseInt
的參數(shù)都是字符串嬉挡,結(jié)果只返回字符串頭部可以轉(zhuǎn)為數(shù)字的部分钝鸽。
如果字符串的第一個(gè)字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號(hào)除外),返回NaN
庞钢。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
所以拔恰,parseInt
的返回值只有兩種可能,要么是一個(gè)十進(jìn)制整數(shù)基括,要么是NaN
颜懊。
如果字符串以0x
或0X
開頭,parseInt
會(huì)將其按照十六進(jìn)制數(shù)解析风皿。
parseInt('0x10') // 16
如果字符串以0
開頭河爹,將其按照10進(jìn)制解析。
parseInt('011') // 11
對(duì)于那些會(huì)自動(dòng)轉(zhuǎn)為科學(xué)計(jì)數(shù)法的數(shù)字桐款,parseInt
會(huì)將科學(xué)計(jì)數(shù)法的表示方法視為字符串咸这,因此導(dǎo)致一些奇怪的結(jié)果。
parseInt(1000000000000000000000.5) // 1
// 等同于
parseInt('1e+21') // 1
parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
(2)進(jìn)制轉(zhuǎn)換
parseInt
方法還可以接受第二個(gè)參數(shù)(2到36之間)魔眨,表示被解析的值的進(jìn)制媳维,返回該值對(duì)應(yīng)的十進(jìn)制數(shù)酿雪。默認(rèn)情況下,parseInt
的第二個(gè)參數(shù)為10侄刽,即默認(rèn)是十進(jìn)制轉(zhuǎn)十進(jìn)制指黎。
parseInt('1000') // 1000
// 等同于
parseInt('1000', 10) // 1000
下面是轉(zhuǎn)換指定進(jìn)制的數(shù)的例子。
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
上面代碼中州丹,二進(jìn)制醋安、六進(jìn)制、八進(jìn)制的1000
当叭,分別等于十進(jìn)制的8茬故、216和512盖灸。這意味著蚁鳖,可以用parseInt
方法進(jìn)行進(jìn)制的轉(zhuǎn)換。
如果第二個(gè)參數(shù)不是數(shù)值赁炎,會(huì)被自動(dòng)轉(zhuǎn)為一個(gè)整數(shù)醉箕。這個(gè)整數(shù)只有在2到36之間,才能得到有意義的結(jié)果徙垫,超出這個(gè)范圍讥裤,則返回NaN
。如果第二個(gè)參數(shù)是0
姻报、undefined
和null
己英,則直接忽略。
parseInt('10', 37) // NaN
parseInt('10', 1) // NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', undefined) // 10
如果字符串包含對(duì)于指定進(jìn)制無(wú)意義的字符吴旋,則從最高位開始损肛,只返回可以轉(zhuǎn)換的數(shù)值。如果最高位無(wú)法轉(zhuǎn)換荣瑟,則直接返回NaN
治拿。
parseInt('1546', 2) // 1
parseInt('546', 2) // NaN
上面代碼中,對(duì)于二進(jìn)制來(lái)說(shuō)笆焰,1
是有意義的字符劫谅,5
、4
嚷掠、6
都是無(wú)意義的字符捏检,所以第一行返回1,第二行返回NaN
不皆。
前面說(shuō)過(guò)贯城,如果parseInt
的第一個(gè)參數(shù)不是字符串,會(huì)被先轉(zhuǎn)為字符串粟焊。這會(huì)導(dǎo)致一些令人意外的結(jié)果冤狡。
parseInt(0x11, 36) // 43
parseInt(0x11, 2) // 1
// 等同于
parseInt(String(0x11), 36)
parseInt(String(0x11), 2)
// 等同于
parseInt('17', 36)
parseInt('17', 2)
上面代碼中孙蒙,十六進(jìn)制的0x11
會(huì)被先轉(zhuǎn)為十進(jìn)制的17,再轉(zhuǎn)為字符串悲雳。然后挎峦,再用36進(jìn)制或二進(jìn)制解讀字符串17
,最后返回結(jié)果43
和1
合瓢。
這種處理方式坦胶,對(duì)于八進(jìn)制的前綴0,尤其需要注意晴楔。
parseInt(011, 2) // NaN
// 等同于
parseInt(String(011), 2)
// 等同于
parseInt(String(9), 2)
上面代碼中顿苇,第一行的011
會(huì)被先轉(zhuǎn)為字符串9
,因?yàn)?code>9不是二進(jìn)制的有效字符税弃,所以返回NaN
纪岁。如果直接計(jì)算parseInt('011', 2)
,011
則是會(huì)被當(dāng)作二進(jìn)制處理则果,返回3幔翰。
JavaScript 不再允許將帶有前綴0的數(shù)字視為八進(jìn)制數(shù),而是要求忽略這個(gè)0
西壮。但是遗增,為了保證兼容性,大部分瀏覽器并沒(méi)有部署這一條規(guī)定款青。
parseFloat()
parseFloat
方法用于將一個(gè)字符串轉(zhuǎn)為浮點(diǎn)數(shù)做修。
parseFloat('3.14') // 3.14
如果字符串符合科學(xué)計(jì)數(shù)法,則會(huì)進(jìn)行相應(yīng)的轉(zhuǎn)換抡草。
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
如果字符串包含不能轉(zhuǎn)為浮點(diǎn)數(shù)的字符饰及,則不再進(jìn)行往后轉(zhuǎn)換,返回已經(jīng)轉(zhuǎn)好的部分渠牲。
parseFloat('3.14more non-digit characters') // 3.14
parseFloat
方法會(huì)自動(dòng)過(guò)濾字符串前導(dǎo)的空格旋炒。
parseFloat('\t\v\r12.34\n ') // 12.34
如果參數(shù)不是字符串,或者字符串的第一個(gè)字符不能轉(zhuǎn)化為浮點(diǎn)數(shù)签杈,則返回NaN
瘫镇。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
上面代碼中,尤其值得注意答姥,parseFloat
會(huì)將空字符串轉(zhuǎn)為NaN
铣除。
這些特點(diǎn)使得parseFloat
的轉(zhuǎn)換結(jié)果不同于Number
函數(shù)。
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
isNaN()
isNaN
方法可以用來(lái)判斷一個(gè)值是否為NaN
鹦付。
isNaN(NaN) // true
isNaN(123) // false
但是尚粘,isNaN
只對(duì)數(shù)值有效,如果傳入其他值敲长,會(huì)被先轉(zhuǎn)成數(shù)值郎嫁。比如秉继,傳入字符串的時(shí)候,字符串會(huì)被先轉(zhuǎn)成NaN
泽铛,所以最后返回true
尚辑,這一點(diǎn)要特別引起注意。也就是說(shuō)盔腔,isNaN
為true
的值杠茬,有可能不是NaN
,而是一個(gè)字符串弛随。
isNaN('Hello') // true
// 相當(dāng)于
isNaN(Number('Hello')) // true
出于同樣的原因瓢喉,對(duì)于對(duì)象和數(shù)組,isNaN
也返回true
舀透。
isNaN({}) // true
// 等同于
isNaN(Number({})) // true
isNaN(['xzy']) // true
// 等同于
isNaN(Number(['xzy'])) // true
但是栓票,對(duì)于空數(shù)組和只有一個(gè)數(shù)值成員的數(shù)組,isNaN
返回false
盐杂。
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
上面代碼之所以返回false
逗载,原因是這些數(shù)組能被Number
函數(shù)轉(zhuǎn)成數(shù)值,請(qǐng)參見《數(shù)據(jù)類型轉(zhuǎn)換》一章链烈。
因此,使用isNaN
之前挚躯,最好判斷一下數(shù)據(jù)類型强衡。
function myIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
判斷NaN
更可靠的方法是,利用NaN
為唯一不等于自身的值的這個(gè)特點(diǎn)码荔,進(jìn)行判斷漩勤。
function myIsNaN(value) {
return value !== value;
}
isFinite()
isFinite
方法返回一個(gè)布爾值,表示某個(gè)值是否為正常的數(shù)值缩搅。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(-1) // true
除了Infinity
越败、-Infinity
和NaN
這三個(gè)值會(huì)返回false
,isFinite
對(duì)于其他的數(shù)值都會(huì)返回true
硼瓣。
參考鏈接
- Dr. Axel Rauschmayer, How numbers are encoded in JavaScript
- Humphry, JavaScript 中 Number 的一些表示上/下限