你不知道的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 运行时在编 ...
随机推荐
- SQLiteHelp
using System; using System.Collections.Generic; using System.Text; using System.Data.SQLite; using S ...
- 请求测试——Fiddler2工具(可以测试POST和Get)
使用参考:http://jingyan.baidu.com/article/dca1fa6fa07000f1a44052f6.html 发送POST请求的时候,需要填写发送类型: 发送JSON格式填写 ...
- hdu 1166 敌兵布阵 【线段树】
好好学一下线段树---- 从0开始----加油- 单点更新的 #include<cstdio> #include<cstring> #include<iostream&g ...
- elasticsearch集群添加节点
最简配置文件: cluster.name: your_cluster_name node.name: your_ip network.host: 0.0.0.0 http.port: your_p ...
- CDR X7正版优惠,3折来袭,好礼相送,行不行动?
意料之中的是,CorelDRAW系列软件在618期间成绩再次突破历史,成为新高.因为X7版本活动在6月15号的才上, 加之在此之前从没有过X7的活动优惠,势头之猛,可想而知,如此一来,官方预定的限量2 ...
- Python 进行网络编程
Date: 2019-06-10 Author: Sun 1. Python TCP通信实现 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: sock ...
- PHP的soap 之 nusoap 的使用
今天不知道为什么想起了soap 这个东西,然后就弄了下,在php上使用的是nusoap. 一些基本的使用,高深的麻烦您自己看手册去 这个软件的下载在http://sourceforge.net/pro ...
- Vue学习之路第一篇(学习准备)
1.开发工具的选择 这个和个人的开发习惯有关,并不做强求,厉害的话用记事本也可以.但是我还是建议用人气比较高的编辑工具,毕竟功能比较全面,开发起来效率比较高. 我之前写前端一直用的是sublimete ...
- 启用Maven的代理访问
1. Maven配置文件 找到文件 {M2_HOME}/conf/settings.xml, 并把你的代理服务器信息配置写入.注:{M2_HOME} => D:\software\yiibai. ...
- [LeetCode] 860. 柠檬水找零 lemonade-change(贪心算法)
思路: 收到5块时,只是添加:收到十块时,添加10块,删除一个5块:收到20块时,添加20,删除一个10块一个5块,或者直接删除3个5块(注意:这里先删除5+10优于3个5) class Soluti ...