目录
Number类型的值包括整数与浮点数两种;
整数又可以根据进制分为十进制、八进制、十六进制整数,八和十六进制整数在参与算数运算时都会被自动转换成十进制整数,在此对八和十六进制不做深究;
Number的数值范围介于-Infinity(负无穷)和Infinity(正无穷)之间(Number.NAGATIVE_INFINITY和Number.POSITIVE_INFINITY分别保存着-Infinity和Infinity;
Number类型采用IEEE754的规则来保存数值(64位双精度),这个规则会造成一些有意思的问题
有两个最有名的例子:
0.1 + 0.2 = 0.30000000000000004;
1000000000000000128 === 1000000000000000127
问题的原因在于究其底层原理:
计算机保存数值采用的是二进制;
计算机保存一个数值的空间是有限的(包括无限循环小数);
加减运算是位运算;
根据以上三点就很好得到答案了:
对于例子1:
0.1与0.2采用二进制表示都是无限循环小数,保存进一个有限空间必然会有精度的损失;
当加法运算时,二进制的0.1与0.2进行位运算,得到一个二进制浮点数,换算成十进制就得到了0.30000000000000004;
对于例子2:
1000000000000000128与1000000000000000127的二进制按位存储的结果是一摸一样的,所以二者的===运算返回true;
注意:永远不要做类似下面的判断:
var a = 0.1,
b = 0.2;
if (a + b == 0.3) {…}
那么在必须用到浮点数加法的时候如何解决这个问题呢?一个最常用的思路就是先将浮点数乘10^n扩大至整数,运算得到结果后除以10^n得到应得的结果;
NaN表示Not a Number;
NaN是一个数值!数值!数值!重要的事情说三遍。也就是说typeof NaN会返回”number“;
NaN参与的任何运算都会得到NaN;
正数 / 0 得到Infinity,负数 / 0 得到-Infinity;
0 / 0 得到NaN;
NaN与任何值都不相等,包括它自己:
NaN == NaN; //false
可以利用isNaN( )判断判断一个值是否为数值,判断前会先对数值进行数据类型转换,看能否转换为数值:
isNaN(true); //false 因为true先转换成了1,false同理
isNaN('123'); //false 因为’123’先转换成了123
isNaN(‘lalala’); //true 不能将’lalala’转换成数值,得到的是NaN
如果isNaN( )传入的参数是个对象,则会先调用该对象的valueOf( )方法,判断返回的值是否可以转换成成数值,如果答案为否,则基于这个返回值再调用对象的toString( )方法,再次判断返回值是否可以转换成数值,并返回最终结果;
有以下几种方式可以将其他类型转换为数值类型:
Number( )函数
+ 一元运算符,与Number( )作用相同
parseInt( )函数
parseFloat( )函数
Number( ):
// Boolean
Number(true); // 1
Number(false); // 0
// Number
Number(123); // 123 没有变化
// null
Number(null); // 0
// undefined
Number(undefined); // NaN
// String
Number(‘123’); // 123
Number(‘ 123’); // 123
Number(‘000123’); // 123
Number(‘1.23’); // 1.23
Number(‘ 001.23’); //1.23
Number(‘0xf’); // 15
Number(‘’); // 0
Number(‘123abc456’); //NaN
Number(‘a123’); //NaN
对象:调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值;
parseInt( ):
可以接收两个参数,第一个参数为需要转换的值,第二个参数指定该值的进制数(即基数,可以省略,由parseInt( )决定如何解析,但不建议省略);
parseInt( )忽略字符串前导空格,直到找到第一个非空格字符,若该字符不是数字字符或负号,则返回NaN;否则继续向后解析,直到遇到第一个非数字字符停止;
parseInt(‘ 123.456abc’); // 123
parseInt(‘abc123’); // NaN
parseInt(‘070’, 8); // 56
parseInt(‘0xf’, 16); //15
parseFloat( ):
与parseInt( )类似,不过是解析到第一个非浮点数字符停止,所以遇到第一个小数点时不会停下来;
parseFloat( )只解析十进制,只接收一个参数,所有16进制格式的数值都会返回0(因为按照规则parseFloat(‘0xf’)只会取到第一个字符’0’;