官术网_书友最值得收藏!

1.2.3 isNaN()函數(shù)與Number.isNaN()函數(shù)對(duì)比

Number類(lèi)型數(shù)據(jù)中存在一個(gè)比較特殊的數(shù)值NaN(Not a Number),它表示應(yīng)該返回?cái)?shù)值卻并未返回?cái)?shù)值的情況。

NaN存在的目的是在某些異常情況下保證程序的正常執(zhí)行。例如0/0,在其他語(yǔ)言中,程序會(huì)直接拋出異常,而在JavaScript中會(huì)返回“NaN”,程序可以正常執(zhí)行。

NaN有兩個(gè)很明顯的特點(diǎn),第一個(gè)是任何涉及NaN的操作都會(huì)返回“NaN”,第二個(gè)是NaN與任何值都不相等,即使是與NaN本身相比。


NaN == NaN;  // false

在判斷NaN時(shí),ES5提供了isNaN()函數(shù),ECMAScript 6(后續(xù)簡(jiǎn)稱(chēng)ES6)為Number類(lèi)型增加了靜態(tài)函數(shù)isNaN()。

既然在ES5中提供了isNaN()函數(shù),為什么要在ES6中專(zhuān)門(mén)增加Number.isNaN()函數(shù)呢??jī)烧咴谑褂蒙嫌惺裁磪^(qū)別呢?

1. isNaN()函數(shù)

首先我們來(lái)看看isNaN()函數(shù)的作用,它用來(lái)確定一個(gè)變量是不是NaN。NaN是一個(gè)Number類(lèi)型的數(shù)值,只不過(guò)這個(gè)值無(wú)法用真實(shí)的數(shù)字表示。

如果傳遞的參數(shù)是Number類(lèi)型數(shù)據(jù),可以很容易判斷是不是NaN。如果傳遞的參數(shù)是非Number類(lèi)型,它返回的結(jié)果往往會(huì)讓人費(fèi)解。

例如下面判斷一個(gè)空對(duì)象{}的代碼。


isNaN({});  // true

空對(duì)象{}明明不是一個(gè)NaN的數(shù)據(jù),應(yīng)該返回的是“false”,為什么會(huì)返回“true”呢?

這里我們首先要知道NaN產(chǎn)生的條件,一方面是在數(shù)據(jù)運(yùn)算時(shí),返回了一個(gè)無(wú)法表示的數(shù)值,例如0 / 0就會(huì)返回“NaN”。有一點(diǎn)需要注意的是除了0 / 0,其他數(shù)據(jù)除以0都返回“Infinity”。

另一方面是在需要做強(qiáng)制類(lèi)型轉(zhuǎn)換時(shí),某些數(shù)據(jù)不能直接轉(zhuǎn)換為數(shù)值類(lèi)型,就會(huì)返回“NaN”,例如1 - 'a' = NaN,因?yàn)樽址?a'無(wú)法參與數(shù)值運(yùn)算。

而isNaN()函數(shù)正好會(huì)進(jìn)行數(shù)據(jù)的類(lèi)型轉(zhuǎn)換,它在處理的時(shí)候會(huì)去判斷傳入的變量值能否轉(zhuǎn)換為數(shù)字,如果能轉(zhuǎn)換成數(shù)字則會(huì)返回“false”,如果無(wú)法轉(zhuǎn)換則會(huì)返回“true”。

接下來(lái)就通過(guò)下面這些代碼來(lái)測(cè)試一下。


isNaN(NaN);       // true
isNaN(unde?ned);  // true
isNaN({});        // true

isNaN(true);      // false,Number(true)會(huì)轉(zhuǎn)換成數(shù)字1
isNaN(null);      // false,Number(null)會(huì)轉(zhuǎn)換成數(shù)字0
isNaN(1);         // false
isNaN('');        // false,Number('')會(huì)轉(zhuǎn)換為成數(shù)字0
isNaN("1");            // false,字符串"1"可以轉(zhuǎn)換成數(shù)字1
isNaN("JavaScript");   // true,字符串"JavaScript"無(wú)法轉(zhuǎn)換成數(shù)字
// Date類(lèi)型
isNaN(new Date());     // false
isNaN(new Date().toString());  // true

Date是一種比較特殊的類(lèi)型,當(dāng)我們調(diào)用new Date()函數(shù)生成的實(shí)例并轉(zhuǎn)換為數(shù)值類(lèi)型時(shí),會(huì)轉(zhuǎn)換為對(duì)應(yīng)的時(shí)間戳,例如下面的代碼。


Number(new Date()); // 1543333199705

因此isNaN(new Date())會(huì)返回“false”。

而當(dāng)我們調(diào)用了toString()函數(shù)時(shí),返回的是一串字符串表示的時(shí)間,無(wú)法轉(zhuǎn)換成數(shù)值類(lèi)型,因此isNaN(new Date().toString())會(huì)返回“true”。

2. Number.isNaN()函數(shù)

既然在全局環(huán)境中有isNaN()函數(shù),為什么在ES6中會(huì)專(zhuān)門(mén)針對(duì)Number類(lèi)型增加一個(gè)isNaN()函數(shù)呢?

這是因?yàn)閕sNaN()函數(shù)本身存在誤導(dǎo)性,而ES6中的Number.isNaN()函數(shù)會(huì)在真正意義上去判斷變量是否為NaN,不會(huì)做數(shù)據(jù)類(lèi)型轉(zhuǎn)換。只有在傳入的值為NaN時(shí),才會(huì)返回“true”,傳入其他任何類(lèi)型的值時(shí)會(huì)返回“false”。

我們可以通過(guò)以下這些代碼做測(cè)試。


Number.isNaN(NaN);        // true
Number.isNaN(unde?ned);   // false
Number.isNaN(null);       // false
Number.isNaN(true);       // false
Number.isNaN('');         // false
Number.isNaN(123);        // false

上面代碼運(yùn)行后,除了傳入NaN會(huì)返回“true”以外,傳入其他的值都會(huì)返回“false”。如果在非ES6環(huán)境中想用ES6中的isNaN()函數(shù),該怎么辦呢?我們有以下兼容性處理方案。


// 兼容性處理
if(!Number.isNaN) {
    Number.isNaN = function (n) {
       return n !== n;
    }
}

因?yàn)樵谒蓄?lèi)型的數(shù)據(jù)中,如果一個(gè)變量和自身作比較,只有在變量值為NaN時(shí)才會(huì)返回“false”,其他情況都是返回“true”。

所以n !== n返回“true”,只有在n為NaN的時(shí)候才成立。

3. 總結(jié)

isNaN()函數(shù)與Number.isNaN()函數(shù)的差別如下。

· isNaN()函數(shù)在判斷是否為NaN時(shí),需要先進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換,只有在無(wú)法轉(zhuǎn)換為數(shù)字時(shí)才會(huì)返回“true”;

· Number.isNaN()函數(shù)在判斷是否為NaN時(shí),只需要判斷傳入的值是否為NaN,并不會(huì)進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換。

主站蜘蛛池模板: 河间市| 收藏| 南华县| 岑溪市| 凯里市| 唐山市| 南木林县| 桐梓县| 延长县| 安宁市| 盐山县| 阿尔山市| 徐汇区| 综艺| 晴隆县| 开平市| 乡宁县| 酉阳| 水城县| 平遥县| 益阳市| 周宁县| 比如县| 寿阳县| 澄江县| 平和县| 洛南县| 内黄县| 文水县| 伊春市| 安顺市| 武强县| 唐河县| 汶川县| 黄浦区| 出国| 新源县| 浮山县| 哈巴河县| 邵阳县| 洛隆县|