[前端日记]1.x.1/解读NaN

Javascript中有一个特殊的对象:NaN,它是「not a number」的缩写。总结了以下几点需要注意,如有错误,烦请指正:P

1. Javascript中返回NaN的情况


就目前所学来看,以下两种情况会返回NaN:

  • 表达式计算
    一个表达式中如果有减号 (-)、乘号 (*) 或 除号 (/) 等运算符时,JS 引擎在计算之前,会试图将表达式的每个分项转化为Number 类型(使用 Number()做转换)。如果转换失败,表达式将返回 NaN 。
    一句话理解:任何数除以、减、乘非数值(undefined、string、object)时,都会直接返回NaN
100 - '2a' ; // NaN 
'100' / '20a'; // NaN 
'20a' * 5 ; // NaN
undefined / 5; // NaN
undefined * "hello" // NaN
  • 类型转换失败
    使用 parseIntparseFloatNumber 将一个非数字的值转化为数字时,表达式返回 NaN
"abc" - 3   // NaN
parseInt("abc")  // NaN
parseFloat("abc") //NaN
Number("abc")    //NaN

NaN带来的坑


陷阱1:typeof NaN // 返回number

这种情况下返回了number。
在JS中,整数和浮点数都统称为Number,除此之外,还有一个特殊的数值类型就是NaN。他不是一个数字,而是一种数值类型,这也解释了typeof NaN // 返回number

陷阱2:NaN == NaN // 返回false

无论相等还是全等,NaN与自身比较都返回false
因为NaN表示一个无法表示的值,而有很多方法来表示一个非数字,所以一个非数字不会等于另一个为NaN的非数字。比如0/0返回NaN,0/'fail'也返回NaN,而0/0 != 0/’fail’,所以NaN == NaN返回false。

陷阱3:判断一个值是否为NaN

如上,==,===均不能用来判断一个值是否是NaN。必须使用Number.isNaN()isNaN函数来检验,下面我们来看下他们的用法。

isNaN()


通常我们用isNaN来判断一个值是否是NaN,如下

isNaN(NaN) // true
isNaN(undefined) // true
isNaN({}) // true

isNaN(true) // false,为1
isNaN(null) // false,为0
isNaN("") // false ,为0
isNaN(" ") // false,带空格的字符串转换为数字为0
isNaN([]) // false,空数组转换为数字为0

isNaN()接收一个参数,参数可以为任意数据类型。如果接收的参数是数字类型,返回false;如果是其他类型(除了数字的任何其他类型),则返回true;

  1. 若接收的参数为数字类型,返回false,表示不是NaN
  2. 若参数为非数字类型,会通过toNumber()将值强制转换为数值,再进行判断。
  3. 如接受的参数是空,比如[](空数组)、“”(空字符串)、null等,会在过程中转换为数字类型的0,从而返回false。

如下代码,在调用isNaN()时,遇到字符串会强制进行隐式转换。

isNaN("1");            // false "1" 被转化为数字 1,因此返回false
isNaN("Hello World"); // true "Hello World" 被隐式转化成数字`NaN`

总结一下isNaN()的坑:
如果传入的参数不是number类型,isNaN()会尝试将参数转换为数值,然后再对转换后的数值进行判断。因此,就算对于能够被转换为数值的数据类型来说(要特别注意,空字符串、布尔、null、空数组会返回0,布尔值会返回对应数值),返回false值也是反直觉的。

说到底,其实是Javascript强制类型转换的坑啊!

ES6新特性 Number.isNaN()


例如,空字符串就明显不是数值,但是还是返回了0,这是相当的反直觉的!

所以,我们能否不进行隐式转换来判断NaN呢?答案是,可以的!

ES6引入了另一种判断方法来填坑——Number.isNaN(x)。通过这个函数来检测x是否是一个非数值,这方法比isNaN()更为可靠。只有在参数是真正的数值类型,且判断后值为 NaN 的时候才会返回 true。

Number.isNaN(NaN)  // true,NaN既是数值类型,返回的又是NaN
Number.isNaN("NaN") // false,这里"NaN"是string,不是数字类型,所以直接返回false

Number.isNaN("hello") // false
isNaN("hello") // true,Number("hello")返回NaN,再判断isNaN(NaN) // true

Number.isNaN({}) // false
isNaN({}) // true,Number({})返回NaN,判断同上

Number.isNaN("") // false
isNaN("") // true

总的来说,Number.isNaN()进行了更严格的判断。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,145评论 0 13
  • 什么是 JavaScript 语言? JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”(script...
    oWSQo阅读 1,790评论 0 1
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,233评论 0 4
  • 关系运算可以通过逻辑运算符 and 和 or 组合,比较的结果可以用 not 来取反意。逻辑运算符的优先级又低于关...
    Ego_1973阅读 446评论 0 0
  • 多肉植物用土五花八门,有的人选择某宝或者论坛贴吧买大神级别的人物配好的现成的多肉土,有的人选择自己去配土。那么,究...
    六六多肉花园阅读 483评论 0 0