`
MirrorAvatar
  • 浏览: 46444 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

理解掌握ECMAScript的Number类型

阅读更多

从哪几个方面来掌握Number类型?

首先,明确一点:变量没有类型,有类型的是变量的值。变量用来存储各个类型的值。

一.Number类型的基本概念

Number类型的值有两种:整数值和浮点数值(浮点数值在某些语言中也被成为双精度数值double-precision)。这两种数值都是用IEEE754格式来表示的。

二.Number类型数值字面量格式有哪些?

1.十进制整数。

最基本的数值字面量格式。

var intNum = 55;//十进制整数
 
2.八进制。

八进制字面值的两个组成部分:第一位必须是零(0),然后是八进制数字序列(0~7)。

八进制使用注意:如果字面值的数值超出了范围,那么前面的零被忽略,后面的数值当做十进制来解析。

var octalNum1 = 070;//八进制的070,十进制的56

var octalNum2 = 079;//字面值“9”超出范围,无效八进制,解析为79

var octalNum3 = 08;//无效的八进制,解析为8
 
3.八进制字面量在严格模式(strict mode)下是无效的,会导致支持的JavaScript引擎抛出错误。
4.十六进制。

十六进制字面值的前两位必须是0x,后跟任何十六进制数字(0~9及A~F)。其中,字母A~F可以大写,也可以小写。

var hexNum1 = 0xA;// 十六进制的10


var hexNum2 = 0x1f;// 十六进制的31
 
5.八进制、十六进制和十进制之间的关系。

在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。

0xA + 070;//66
 

三.浮点数值

1.什么是浮点数值?

所谓浮点数值,就是该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。两大必须的组成部分。

var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1;  //有效,但是不推荐
 
2.浮点数值和整数值之间有什么关系?

它们之间有转换关系,浮点数值向整数值的转换。

  • 保存浮点数值需要的内存空间是保存整数值的两倍。
  • ECMAScript会不失时机地将浮点数值转换为整数值。
  • 转换条件有两种:小数点后没有跟数字,浮点数本身表示一个整数(如1.0)。
//可以在浏览器控制台进行验证
var floatNum4 = 1.;  //解析为1,按照前面的观点,“1.” 其实不算是个浮点数,因为小数点后没有数字。
var floatNum5 = 10.0;  //解析为10
 
3.浮点数值和极大、极小数值之间有什么关系?

它们之间关系就在于科学计数法的表示。

极大数值的表示:

var floatNum = 3.125e7; //等于31250000,表示,3.125乘以,10的7次方。当然,科学计数法前面的数也可以是整数值。
 

极小数值的表示:

var a = 0.00000000000000003;
console.log(a);//3e-17
 

0.00000000000000003可用3e-17来表示。

在默认情况下,ECMASctipt会将那些小数点后面带有6个零以上的浮点数值转换为以e表示法表示的数值。可在浏览器控制台进行验证。

4.IEEE754浮点数值的通病:
0.1 + 0.2;  // 等于0.30000000000000004

// 所以不要做这样的测试!
if (a + b == 0.3){
    alert("You got 0.3.");
}

//另外
0.05 + 0.25;  //0.3 没问题
0.15 + 0.15;  //0.3 没问题
 

通病有什么解决办法?

通过比较,两个数差值的绝对值和一个叫Machine Epsilon的数值来进行比较。通常这个数值为2^-52 (2.220446049250313e-16)。

在ES6中,Number.EPSILON就是表示这个数。附上代码:

//安全性检测
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;

numbersCloseEnoughToEqual( a, b );                  // true
numbersCloseEnoughToEqual( 0.0000001, 0.0000002 );  // false
 

四.数值范围

1. 数值范围。

最小数值:Number.MIN_VALUE。大多数浏览器是5e-324。

最大数值:Number.MAX_VALUE。大多数浏览器是1.7976931348623157e+308。

2. 超出范围的数值如何表示?

用特殊的Infinity值来表示。

正数超出范围后,数值自动转换为Infinity(正无穷)。Infinity存放于Number.NEGATIVE_INFINITY中。

负数超出范围后,数值自动转换为-Infinity(负无穷)。-Infinity存放于Number.POSITIVE_INFINITY中。

Infinity是个数值,但是不能参与数值计算。

typeof Infinity;  //"number"
 
3. 如何判断一个数是否在有效范围内?

用isFinite()方法。

var result = Number.MAX_VALUE + Number.MAX_VALUE;

alert(isFinite(result));//false
 

五.NaN

1.NaN的基本概念

NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。

2.NaN的两个不同寻常的特点是什么?
  • 任何涉及NaN的操作(例如NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题。
  • 其次,NaN与任何值都不相等,包括NaN本身。
alert(NaN == NaN); //false
 
3.isNaN()的用法

判断这个参数是否“不是数值”。

alert(isNaN(NaN));  //true

alert(isNaN(10)); //false

alert(isNaN("10"));  //false "10"转换成了10

alert(isNaN("blue")); //true

alert(isNaN(true));  //false, true被转化成1
 

六.数值转换

数值转换用到3个函数:Number()、parseInt()和parseFloat()。

1.Number()的转换规则
  • Boolean: true -> 1 ;false -> 0;
  • 数字,简单的传入和传出
  • null -> 0
  • undefined -> NaN
  • String类型的值:
    • "1" -> 1
    • "011" -> 11 //前面的0被忽略
    • "1.1" -> 1.1
    • 字符串包含十六进制,会转换成十进制。Number("0x1f");// 31
    • "" -> 0 空转换成0
    • 除以上格式,其余都转换成NaN
  • Object 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。

总结:Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数。

2.parseInt()的转换规则
  • 如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN
parseInt("dd12"); //NaN

parseInt("");   //NaN

Number("");  // 0
 
  • 如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。
parseInt("1234ddd");  //1234

parseInt("33.3");  //33 "."不是有效的数字字符。
 
  • parseInt八进制在ES3和ES5有区别
//ECMAScript 3认为是56(八进制),ECMAScript 5认为是0(十进制)
var num = parseInt("070");
 
  • 消除上述困惑,需要添加基数
var num = parseInt("0xAF", 16); // 175
 
  • parseInt转换十六进制数需注意:如果指定了16作为第二个参数,字符串可以不带前面的"0x"
var num1 = parseInt("AF", 16);  //175

var num2 = parseInt("AF");  //NaN
 
  • 最佳实践:多数情况下,我们要解析的都是十进制数值,因此始终将10作为第二个参数是非常必要的。
3.parseFloat()的用法
  • 转换规则:

parseFloat()也是从第一个字符(位置0)开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。

parseFloat("22.3.2");  // 22.3
 
  • parseFloat和parseInt的区别

    parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法。

    十六进制格式的字符串则始终会被转换成0。

//1234 (整数)
var num1 = parseFloat("1234blue");
//0
var num2 = parseFloat("0xA");
//22.5
var num3 = parseFloat("22.5");
//22.34
var num4 = parseFloat("22.34.5");
//908.5
var num5 = parseFloat("0908.5");
//31250000
var num6 = parseFloat("3.125e7");
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics