在JavaScript
,所有的数字都是64-bit双精度浮点类型。没有特定的整数数据类型。除了可以表示浮点数,the number type has three symbolic values: +Infinity
、-Infinity
、NaN
。
Numbers
Decimal numbers – 十进制数据
12345678
42
//如果第一个数字为零
0888 //被当作十进制处理
0777 //被当作八进制处理
Binary numbers – 二进制数据
var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648
var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
Octal numbers – 八进制数据
八进制数字语法是以0
为开头的。假如0
后面的数字不在0
到7
的范围内,该数字将会被转换成十进制数字。
var n = 0755; // 493
var m = 0644; // 420
在
ECMAScript 5
严格模式下禁止使用八进制语法,但是通过在八进制数字添加一个前缀0
就可以被所有的浏览器支持。在ECMAScript 6
中使用八进制数字是需要给一个数字添加前缀0o
。
var a = 0o10; // ES6 :八进制
Hexadecimal numbers – 十六进制
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF // 81985529216486900
0XA // 10
指数形式 – EXponentiation
1E3 // 1000
2e6 // 2000000
0.1e2 // 10
二进制浮点数的最大问题
二进制浮点数最大问题,是会出现如下情况:
0.1 + 0.2 === 0.3; //false
为什么呢,因为二进制浮点数中的0.1
和0.2
并不十分准确,所以他们相加的结果并非刚好等于0.3
,而是一个比较接近于数字0.30000000000000004
,所以判断条件是false
。
那如何判断相等呢?
最常见的方法是设置一个误差范围值,通常称为机器精度(machine epsilon),对JavaScript
的数字来说,这个值通常是2^-52(2.220446049250313e-16)
。从ES6
开始,该值定义在Number.EPSILON
中,当然你可以为ES6
之前的版本写polyfill。
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
特殊的数字
NaN
NaN
意指不是一个数字(not a number)。可以理解为失败数值、失败数值、坏数值。
var a = 2 / "foo"; //NaN
console.log(typeof a === "number"); //true
很奇怪的吧,既然不是数字,却又是number
类型,或者我们可以称之为不是数字的数字。
NaN
是一个特殊的值,它和自身不等,是唯一一个非自相反的值,即NaN !=NaN
为true
。所以,我们没办法直接与NaN
进行比较来判断,有什么其他办法吗?有的,就是使用内建的全局工具函数isNaN()
。但这个函数不太准确,如:
var a = 2 / "foo", b = "foo";
a; //NaN
b; //"foo"
window.isNaN(a); //true
window.isNaN(b); //true
b
既不是一个数字,当然也不是NaN
,这个时候window.isNaN()
就出现了错误,这个bug自JavaScript问世以来就一直存在。
从ES6
开始,我们使用工具函数Number.isNaN()
来判断。我们尽量使用该函数来进行判断。
无穷数 – Infinity & -Infinity
零值 – 0 & -0
Object.is()
ES6
中心加入一个工具方法Object.is()
来判断两个值是否绝对相等,可以用来处理上述所有的特殊情况。
var a = 2 / "foo", b = -3 * 0;
Object.is(a, NaN); //true
Object.is(b, -0); //true
Object.is(b,0); //false
数字对象 – Number object
数字的属性
内置的Number
对象有一些数字化常量属性:
Number.MAX_VALUE
可表示的最大值:2^53 - 1
Number.MIN_VALUE
可表示的最小值:-(2^53 - 1)
Number.NaN
特指”非数字“Number.NEGATIVE_INFINITY
特指“负无穷”;在溢出时返回Number.POSITIVE_INFINITY
特指“正无穷”;在溢出时返回Number.MIN_SAFE_INTEGER
JavaScript最小安全整数Number.MAX_SAFE_INTEGER
JavaScript最大安全整数
数字的方法
Number.parseFloat()
把字符串参数解析成浮点数,和全局方法parseFloat()
作用一致Number.parseInt()
把字符串解析成特定基数对应的整型数字,和全局方法parseInt()
作用一致Number.isFinite()
判断传递的值是否为有限数字Number.isInteger()
整数检测:判断传递的值是否为整数Number.isNaN()
判断传递的值是否为NaN
,是全局函数isNaN()
的健壮版本Number.isSafeInteger()
判断传递的值是否为安全整数
Number.prototype中的方法
因为数字值可以使用Number
对象进行封装,所以可以调用Number.prototype
中的方法。
toExponential()
返回一个数字的指数形式的字符串toFixed()
返回指定小数位数的显示位数,如var a=123,b=a.toFixed(2)//b=123.00
toPrecision()
返回一个指定精度的数字,如var a=123,b=a.toPrecision(2)//b=1.2e+2
需要注意的是.
运算符,会被优先识别为数字常量的一部分。如:
42.toFixed(3);//SyntaxError
(42).toFixed(3);//42.000
42..toFixed(3);//42.000
42.toFixed(3)
是错误语法,因为.
被视为42.
的一部分。
Math object
对于内置的Math
数字常数项和函数也有一些属性和方法。具体参见。
Data object – 日期对象
JavaScript
没有日期数据类型。但是你可以在你的程序里使用Date
对象和其方法来处理日期和时间。Date
对象有大量的设置、获取和操作日期的方法。 它并不含有任何属性。
创建一个日期对象:
var dateObjectName = new Date([parameters]);
- 无参数: 创建今天的日期和时间 例如:
var today = new Data()
- 一个符合以下格式的表示日期的字符串: “月 日, 年 时:分:秒.” 例如:
var Xmas95 = new Date("December 25, 1995 13:30:00")
如果你省略时、分、秒,那么他们的值将被设置为0
- 一个年,月,日的整型值的集合,例如:
var Xmas95 = new Date(1995, 11, 25)
- 一个年,月,日,时,分,秒的集合,例如:
var Xmas95 = new Date(1995, 11, 25, 9, 30, 0)
Date对象的方法
处理日期时间的Date
对象方法可分为以下几类:
set
方法, 用于设置Date
对象的日期和时间的值get
方法, 用于获取`Date对象的日期和时间的值to
方法, 用于返回Date
对象的字符串格式的值parse
和UTC
方法, 用于解析Date
字符串
例如:
var Xmas95 = new Date("December 25, 1995");
那么,Xmas95.getMonth()
返回11
,Xmas95.getFullYear()
返回1995
。
以下代码展示了今年剩下的天数:
var today = new Date();
var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // 设置日和月,注意,月份是0-11
endYear.setFullYear(today.getFullYear()); // 把年设置为今年
var msPerDay = 24 * 60 * 60 * 1000; // 每天的毫秒数
var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
var daysLeft = Math.round(daysLeft); //返回这一年剩下的天数
getTime()
返回从1970年1月1日00:00:00的毫秒数
parse()
方法对于从日期字符串赋值给现有的Date
对象很有用。
var IPOdate = new Date();
IPOdate.setTime(Date.parse("Aug 9, 1995"));