OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

JavaScript中NaN的秘密


分享到
分类 JS学习   关键字 JavaScript   发布 ourjs  1401154447099
注意 转载须保留原文链接,译文链接,作者译者等信息。  

NaN,不是一个数字,是一种特殊的值来代表不可表示的值,使用typeof或其他任何与之比较的处理方式,‘NaN’则会引起一些混乱,

一些操作会导致NaN值的产生。这里有些例子:

Math.sqrt(-2)
Math.log(-1)
0/0
parseFloat('foo')


对于很多JavaScript的初学者来说,它的第一个陷阱是调用typeof时返回结果的通常是你想不到的:

console.log(typeof NaN);   // 'number'


这情情况下,NaN并不意味着是一个数字,它的类型是数字。明白吗?

保持冷静,因为下面还有很多混乱的地方。让我们比较两个NaN:

var x = Math.sqrt(-2);
var y = Math.log(-1);
console.log(x == y);      // false


也许这是因为我们没有使用严格等价(===)操作?显然不是。

var x = Math.sqrt(-2);
var y = Math.log(-1);
console.log(x === y);      // false


好吧!难道是因为这两个NaN是从不同的操作产生出来的?那么这样...

var x = Math.sqrt(-2);
var y = Math.sqrt(-2);
console.log(x == y);      // false


再疯狂一点

var x = Math.sqrt(-2);
console.log(x == x);      // false


直接比较两个NaN呢?

console.log(NaN === NaN); // false


因为有很多方法来表示一个非数字,所以一个非数字不会等于另一个为NaN的非数字,它还是有一定道理的。不过这也是我为什么时而崩溃的原因:

这是对你的提醒,NaN的意思是“不为NaN".
— Ariya Hidayat (@AriyaHidayat)

 

为了解决这个问题,本来我打算向ECMAScript 7提交该方案的

GarlicNaN != NaN


但是当然,解决方案现在已经有了。
让我们认识一下全局函数isNaN:

console.log(isNaN(NaN));      // true


唉,不过 isNaN() 也有它自己的很多缺陷呀:

console.log(isNaN('hello'));  // true
console.log(isNaN(['x']));    // true
console.log(isNaN({}));       // true


这样又产生 了很多不同的解决方案。其中一个是利用 了NaN的非反射性质(例如, 看看 Kit Cambridge 的笔记)

var My = {
  isNaN: function (x) { return x !== x; }
}


另外一个例子是先检查值的类型(防止强制转换):

My.isNaN = function(x) { return typeof x === 'number' && isNaN(x)};


不过幸运的是,在即将到来的ECMAScript 6中, 有一个Number.isNaN() 方法提供可靠的NaN值检测。(随便说下,你已经可以在最新版的Chrome和firefox中使用这个方法了)。在2014年4月的规范草稿中,有着如下记载:

当传入一个数字参数并调用 Number.isNaN 时,会进行以下几步:

1. 如果Type(number) 不是数字, 返回 false.
2. 如果数字是NaN, 返回true.
3. 其他情况,返回false.


换句话说,只有在参数是真正的NaN时,才会返回true 

console.log(Number.isNaN(NaN));            // true
console.log(Number.isNaN(Math.sqrt(-2))); // true
console.log(Number.isNaN('hello'));        // false
console.log(Number.isNaN(['x']));          // false
console.log(Number.isNaN({}));             // false


下一次,当你需要处理NaN时,要格外小心了。

 

 

附: Poetro 的评论

这是 IEEE 754 定义的NaN标准, 跟JavaScript无关。

"在计算中, NaN, 代表一个非数字, 是用来呈现未定义(undefined)和不可呈现(unrepresentable)的数据类型, 尤其是在浮点计算中。"
"与NaN的比较会一直返回一个无序的结果,甚至跟它自己比较。"

原文地址: 点此
社区评论 ( Beta版 )
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. 编程是一个没有前途的工作
  2. 是什么让Node.js比Java更快?
  3. 现在,你为什么应该学Node.js
  4. 我不想雇佣女性
  5. Google正在拖互联网的后腿
  6. 使用集群(recluster)扩展多线程Node.JS
  7. 用JavaScript的5个原因
  8. 趣图:在NodeJS程序中有未处理的异常
  9. 有关GO和Erlang的一些思考
  10. jQuery:在一个回调中处理多个请求
  11. AirJD-简单好用的免费建站工具

 相关阅读 - JS学习
  1. jQuery:在一个回调中处理多个请求
  2. 使用集群(recluster)扩展多线程Node.JS
  3. 抛弃jQuery,深入原生的JavaScript
  4. 使用Backbone构建精美应用的7条建议
  5. 在jQuery API文档中并未提及的get用法,只有读了源码才会知道哦
  6. 如何在一个VPS上连接Node.js到一个MongoDB数据库?
  7. 用Orchestrate 5步快速创建Node.js应用
  8. iFrame的妙用
  9. JavaScript的MVC模式向导
  10. 快乐Node程序员的10个习惯

 关键字 - JavaScript
  1. 如何用CSS将select/option文本居中或居右对齐
  2. 给checkbox选择框设置不选中时的值
  3. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
  4. JavaScript中怪异的地方
  5. 在JavaScript中创建命名空间的几种写法
  6. JavaScript中的继承,构造函数以及new关键字的作用
  7. 纽约时报使用Html5 WebRTC记录访问者IP地址
  8. 正则中test、exec、match的简单区别,以及括号的用法
  9. NativeScript的工作原理:用JavaScript调用原生API实现跨平台
  10. 2015年的JavaScript:Angular之类的框架将被库取代

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号