你不知道的JavaScript(四)数值
JS中只有一种数值类型,即number。不管是整数还是小数都属于number类型,事实上JS并不区分小数和整数。
<div>
<script type="text/javascript">
var num1 = 40.00;
var num2 = 40;
alert(num1 === num2);//alert true
</script>
</div>
我们对40.00和40使用运算符===进行比较发现返回true,也就是说二者完全相同。和绝大多数流行的脚本语言一样,JS语言的number类型基于IEEE 754标准实现。IEEE 754定义了如何在计算机中存储和表示浮点数,关于它的细节,有兴趣的朋友可以参考维基百科对IEEE 754的说明。
IEEE 754:http://en.wikipedia.org/wiki/IEEE_754-1985
下面来看一下数值类型的一些不常见的书写方式。
<script type="text/javascript">
var num1 = 0.42;
var num2 = .42;
alert(num1 === num2);
var num3 = 42.0;
var num4 = 42.;
alert(num3 === num4);
</script>
小数点前面为0时,可以省略,.42也是合法的数字。小数点后面全部为0时,也可以省略小数点后面的部分。.42和42.虽然是合法的数字,但是为了代码的可读性,我们通常不会这样写。
再来看看JS数值比较中,比较容易让人产生困惑的问题:
<script type="text/javascript">
alert((0.1 + 0.2) === 0.3); //false
</script>
我们使用(0.1 + 0.2) === 0.3
,按照正常的编程逻辑,该表达式应该返回true才对,但这里偏偏返回的是false。这是什么原因呢?
首先需要明确的一点是,这并不是JavaScript语言的问题,所有使用IEEE 754标准实现浮点数的语言都要面对这个问题。下面笔者就来解释一下这个原因,大家都知道任何两个数(例如0.1和0.2)之间都有无数多个数,每一个数都在计算机中表示出来是不可能的。对于一个浮点数运算,计算机并不能精准的计算出它的结果,而是尽可能的接近它。也就是说(0.1 + 0.2)
的计算结果并不是精确的等于0.3,可能是0.30000000000000004
,所以二者也就不可能相等。针对这种情况我们通常会这样处理,如果两个浮点数之差的绝对值小于某一个范围,我们就认为这两个浮点数相等。
有了这些理论基础,我们可以通过自定义函数解决浮点数比较问题,代码如下:
if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
}
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
alert( numbersCloseEnoughToEqual( a, b ));//true
接着介绍一下number类型中几个特殊的值:
1.NaN,它表示该值不是一个数值,是不是很奇怪,看下面的代码:
<script type="text/javascript">
var num = 1/"abc";
alert(num);//NaN
alert(typeof num);//number
alert(num === NaN);//false
alert(isNaN(num));//true
</script>
我们用数字除以一个字符串,结果为NaN,它表明该计算结果不是一个数值。使用typeof操作符查看类型,确实是number类型。接下来”奇怪”的事情又来了,我们用===运算符和NaN进行比较,发现结果又为false。这个问题ECMAScript规范中有提到过,NaN不等于任何一个NaN,我们可以使用JS内置函数isNaN来判断一个值是否是NaN。
2.Infinity与-Infinity,Infinity表示正无穷大,-Infinity表示负无穷大。
<script type="text/javascript">
var num1 = 100/0;
var num2 = -100/0;
alert(num1);//Infinity
alert(num2);//-Infinity
alert(typeof num1);//number
alert(typeof num2);//number
alert(num1 + num2);//NaN
alert(num1 + num1);//Infinity
alert(num2 + num2);//-Infinity
</script>
大多数语言中,一个数与0相乘都会抛出运行时异常,例如Java中会抛出java.lang.ArithmeticException
异常,但是JavaScript中则不会,正数与零相除的结果为正无穷Infinity,负数与零相除的结果为-Infinity,它们两个都是number类型的值,Infinity与-Infinity相加结果为NaN,两个Infinity相加结果还是Infinity,两个-Infinity相加也还是-Infinity。相减、相乘和相除的情况读者可以自己写代码测试。
你不知道的JavaScript(四)数值的更多相关文章
- JavaScript四种数值取整方法
一.Math.trunc() 1.定义 Math.trunc()方法去除数字的小数部分,保留整数部分. 2.语法 Math.trunc(value) 3.示例 console.log(Math.tru ...
- 读书笔记-你不知道的JavaScript(上)
本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...
- 《你不知道的 JavaScript 上卷》 学习笔记
第一部分: 作用域和闭包 一.作用域 1. 作用域:存储变量并且查找变量的规则 2. 源代码在执行之前(编译)会经历三个步骤: 分词/此法分析:将代码字符串分解成有意义的代码块(词法单元) 解析/语法 ...
- 《你不知道的JavaScript》整理(二)——this
最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,这次研究了一下“this”. 当一个函数被调用时,会创建一个活动记录(执行上下文). 这个记录会包含函 ...
- 《你不知道的JavaScript》整理(一)——作用域、提升与闭包
最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,里面分析了很多基础性的概念. 可以更全面深入的理解JavaScript深层面的知识点. 一.函数作用域 ...
- 从头开始学JavaScript (四)——操作符
原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...
- JavaScript中的this(你不知道的JavaScript)
JavaScript中的this,刚接触JavaScript时大家都在大肆渲染说其多么多么的灵巧重要,然而自己并不关心:随着自己对JavaScript一步步深入了解,突然恍然大悟,原来它真的很重要!所 ...
- 读《你不知道的JavaScript(上卷)》后感-浅谈JavaScript作用域(一)
原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们,也入手看看这 ...
- JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)
前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...
- 【你不知道的javaScript 上卷 笔记3】javaScript中的声明提升表现
console.log( a ); var a = 2; 执行输出undefined a = 2; var a; console.log( a ); 执行输出2 说明:javaScript 运行时在编 ...
随机推荐
- CSS3背景 制作导航菜单综合练习题
CSS3背景 制作导航菜单综合练习题 小伙伴们,根据所学知识,使用CSS3实现下图的导航菜单效果 任务 1.制作导航圆角 提示:使用border-radius实现圆角 2.制作导航立体风格 提示:使用 ...
- C语言整数类型在X86和X64下的字节大小
C声明 32位机器(X86) 64位机器(X64) char 1 1 short int 2 2 int 4 4 long int 4 8 long long int 8 8 char * 4 8 f ...
- Hibernate框架学习(八)——查询-HQL语法
一.单表查询 1.基础语法 2.排序 3.条件 4.分页 5.聚合 6.投影 二.多表查询 1.回顾原生SQL 1>交叉连接-笛卡尔积(避免)select * from A,B; 2>内连 ...
- Maven配置,使用IntelliJ IDEA和Maven创建Java Web项目
1. 下载Maven 官方地址:http://maven.apache.org/download.cgi 解压并新建一个本地仓库文件夹 2.配置本地仓库路径 3.配置maven环境变量 4 ...
- NotFoundHttpException
报错:NotFoundHttpException 这种一般都是路由配置错误
- [LUOGU]2016 Sam数
我本来想看看SAM,就看见了这个.. 这道题很容易让人想到数位DP,用\(f[i][j]\)表示考虑到第\(i\)位,最后一位是\(j\)的方案数.看到1e18,直接矩阵快速幂加速,因为它每位转移都是 ...
- 每日Linux命令--不完整命令
配置文件优化,即把默认的空行还有#注释行去掉,优化前先拷贝一份配置文件 egrep -v '^$|#' 拷贝的配置文件 > 原配置文件 mysql如何修改root用户的密码 方法1: 用SET ...
- 新手学python-Day4-作业
购物车程序 要求: 1.启动程序后,让用户输入工资,然后打印商品列表 2.允许用户根据商品编号购买商品 3.用户选择商品后,检查余额是否足够,够了就扣款,不够就提醒 4.可随时退出,退出时,打印已购买 ...
- mycql 基本mysql语句(增删改查)
操作文件夹(库) 增 (增加一个库 db1 ) create database db1 charset utf8; 查 # 查看当前创建的数据库 show create database db1; # ...
- DelayQueue延时队列示例
介绍: DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素.该队列的头部是延迟期满后保存时间最长的Delayed 元素. 使用场景: 缓存系统的设计,缓存中的对象,超过了空闲时间 ...