javascript类型系统之Number

jopen 8年前

前面的话

javascript只有一种数字类型,既可以表示32位的整数,还可以表示64位的浮点数。javascript使用IEEE754格式来表示数字,存在浮点计算精度问题

整数

javascript的整数表示共有三种字面量格式是十进制、八进制、十六进制。但在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值

[注意]javascript中可以保存正0和负0,且被认为相等

[1]八进制字面值的第一位必须是0,然后是八进制数字序列(0-7)

[注意]如果字面值中的数值超出了范围,那么前导0将被忽略,后面的数值被当作十进制数解析。八进制字面量在严格模式下是无效的,会导致javascript抛出错误

[2]十六进制字面值的前两位必须是0x,后跟十六进制数字序列,字母可大写可小写

[注意]十六进制中字面值中的数值超出范围,如出现g、h等会报错

console.log(+0);//0  console.log(-0);//-0  console.log((+0) === (-0));//true
//num8代表8进制数,num16代表16进制数  var num8 = 012;  console.log(num8);//10  var num8 = 09;  console.log(num8);//9  var num16 = 0x11;  console.log(num16);//17  var num16 = 0xg;//报错  console.log(num16);

浮点数

浮点数是指有小数点或指数形式的数字。由于浮点型数值需要的内存空间是保存整数值的两倍,因此javascript会不失时机地将浮点数值转换成整数值,若小数点后没有跟任何数字或者浮点值本身表示的就是一个整数,这个数值会作为整数值来保存

[digits][.digits][(E|e)[(+|-)]digits]

[注意]浮点数只可用十进制表示

var num1 = 1.1;  var num2 = 1.;  var num3 = .1;   console.log(num1,num2,num3);//1.1,1,0.1
var num1 = 011.1;//报错  var num2 = 0x11.1;//报错  var num3 = 011e1;//报错  var num4 = 0x11e1;//出错,会被识别成整数,结果为4577

科学计数法

对于极大或者极小的数,可以用科学计数法e来表示的浮点数值来表示。默认情况下,javascript会将小于1且小数点后面带有6个0以上的浮点数值转换为以e表示法表示的数值

var num1 = 10e1;//100  var num2 = 10.1e-1;//1.01  var num3 = 1.0000001;//1.0000001  var num4 = 0.0000001;//1e-7  var num5 = 0.000001;//0.000001  console.log(num1,num2,num3,num4,num5);

舍入误差

javascript中的数字的最高精度是17位(若小于1,则为小数点后17位;若大于1,则去掉小数点后整体保留17位),但基于IEEE754数值的浮点计算的通病是舍入误差的问题

console.log(0.123456789012345678);//0.12345678901234568  console.log(0.123456789012345678+0.000000000000000004);//0.12345678901234568  console.log(1.123456789012345678);//1.1234567890123457  console.log(10.123456789012345678);//10.123456789012346  console.log(12345678901234567890);//12345678901234567000  console.log(0.1+0.2);//0.300000000000000004

数值范围

javascript中的数值范围(正数)是Number.MIN_VALUE —— Number.MAX_VALUE

//5e-324,1.7976931348623157e+308  console.log(Number.MIN_VALUE,Number.MAX_VALUE)

Infinity

如果超出正数范围,输出Infinity(正无穷大),超出负数范围,输出-Infinity(负无穷大)

console.log(Number.MAX_VALUE+1 === Number.MAX_VALUE);//true  console.log(Number.MAX_VALUE+ Number.MAX_VALUE === Infinity);//true  console.log(Number.MIN_VALUE+1);//1  console.log(Number.MIN_VALUE-1);//-1  console.log(-Number.MAX_VALUE-Number.MAX_VALUE);//-Infinity

+Infinity的等价值是Number.POSITIVE_INFINITY;-Infinity的等价值是Number.NEGATIVE_INFINITY

[注意]+-Infinity不能参与数值计算

console.log(Number.POSITIVE_INFINITY === Infinity)//true  console.log(Number.NEGATIVE_INFINITY === -Infinity)//true  console.log(Infinity - 1);//Infinity  console.log(Infinity - Infinity);//NaN

可以用isFinite()来确定一个数值是不是有穷的,包含着隐式类型转换Number()。如果是无穷数或者NaN时返回false,否则为true

console.log(isFinite(Infinity))//false  console.log(isFinite(NaN))//false  console.log(isFinite(Number.MAX_VALUE))//true

NaN

NaN(not a number)表示非数字,NaN与任何值都不相等,包括NaN本身,且任何涉及NaN的操作都会返回NaN。isNaN()来判断这个数字是不是NaN,包含着隐式类型转换Number()

console.log(NaN == NaN);//false  console.log(NaN == Infinity);//false  console.log(isNaN(Infinity));//false  console.log(isNaN(0));//false  console.log(isNaN(NaN));//true

数值转换

有3个函数可以把非数值转换成数值:Number()、parseInt()和parseFloat()

Number()

Number()可用于任何数据类型的转换

Number(true): 1 || Number(false):0

Number(各种进制的数字):运算后的十进制的数字,如1.0或1.或01会以1输出

Number(undefined):NaN

Number(null):0

console.log(Number(true),Number(false));//1 0  console.log(Number(11),Number(011),Number(0x11));//11 9 17  console.log(Number(undefined),Number(null));//NaN 0

Number(字符串):

在解析字符串时会识别前置空格并去掉

Number(只包含十进制或十六进制的数字的字符串):运算后的十进制的数字

[注意]字符串中不识别八进制,按照十进制数字处理

Number(''和' '):0

Number(其他情况的字符串):NaN

[注意]字符串'1.2.'不会报错,但数字1.2.会报错

console.log(Number('    123'));//123  console.log(Number('1.2.'));//NaN  console.log(Number('1.2.'));//报错  console.log(Number(''),Number(' '));//0 0   console.log(Number('11'),Number('011'),Number('0x11'));//11 11 17  console.log(Number('abc'));//NaN

Number(对象):

Number([]和[0]和[-0]):0

Number([数字]):运算后的数字

Number([1,2]和{}和其他对象):NaN

console.log(Number([]),Number([0]),Number([-0]),Number([0,0]));//0 0 0 NaN  console.log(Number([1]),Number([-1]));//1 -1  console.log(Number([1,2]),Number({}));//NaN NaN

[注意]可以用一个值-0来将其转换成一个数字,有隐式类型转换Number()

console.log(typeof ('123'-0),'123'-0);//number 123  console.log(typeof ('123px'-0),'123px'-0);//number NaN  console.log(typeof (true-0),true-0);//number 1   console.log(typeof ([]-0),[]-0);//number 0

parseInt()

parseInt()专门用于把字符串转换成数值。在转换字符串时,会忽略字符串前面的空格,直到找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt()就会返回NaN。如果是,则继续解析,直到解析完成或者遇到非数字字符

console.log(parseInt('    123px'));//123  console.log(parseInt('   123   '));//123  console.log(parseInt(' -123px'));//-123  console.log(parseInt('a123px'));//NaN  console.log(parseInt('0 123px'));//0

parseInt()可以识别出各种进制的数字,输出的是运算后的十进制的数字,如1.0或1.或01会以1输出。在解析八进制字面量的字符串,ECMAScript3会解析八进制,但ECMAScript5没有解析八进制的能力

console.log(parseInt('11'));//11  console.log(parseInt(11));//11  console.log(parseInt('11.1'));//11  console.log(parseInt(11.1));//11  console.log(parseInt('011'));//11  console.log(parseInt(011));//9  console.log(parseInt('011.1'));//11  console.log(parseInt(011.1));//报错  console.log(parseInt('0x11'));//17  console.log(parseInt(0x11));//17  console.log(parseInt('0x11.1'));//17  console.log(parseInt(0x11.1));//报错

parseInt()函数提供第二个参数,表示多少进制

console.log(parseInt('11',2));//3  console.log(parseInt('11',8));//9  console.log(parseInt('11',10));//11  console.log(parseInt('11',16));//17

因为parseInt()是专门用来处理字符串转换数字的,所以parseInt处理非字符串和数字类型时输出NaN

[注意]]parse Int ([数字或字符串])输出对应的数字

console.log(parseInt(null),parseInt(undefined));//NaN NaN  console.log(parseInt(true),parseInt(false));//NaN NaN  console.log(parseInt([]),parseInt(['2.5px']),parseInt([2.5]));//NaN 2 2  console.log(parseInt(''),parseInt(' '),parseInt({}));//NaN NaN NaN

parseFloat()

类似于parseInt(),专门用于字符串转换数字。解析时会忽略字符串前面的空格,直到找到第一个非空格字符,然后一直解析到字符串末尾或一个无效的浮点数字字符为止

console.log(parseFloat('    0123.px'));//123  console.log(parseFloat('    123.px'));//123  console.log(parseFloat('    123.1px'));//123.1  console.log(parseFloat('   123.1.2px   '));//123.1  console.log(parseFloat(' -123.0px'));//-123  console.log(parseFloat('.123.1px'));//0.123  console.log(parseFloat('0 123px'));//0

parseFloat()可以识别不同进制的数字,但只能解析十进制字符串

console.log(parseFloat('11'));//11  console.log(parseFloat(11));//11  console.log(parseFloat('11.1'));//11.1  console.log(parseFloat(11.1));//11.1  console.log(parseFloat('011'));//11  console.log(parseFloat(011));//9  console.log(parseFloat('011.1'));//11.1  console.log(parseFloat(011.1));//报错  console.log(parseFloat('0x11'));//0  console.log(parseFloat(0x11));//17  console.log(parseFloat('0x11.1'));//0  console.log(parseFloat(0x11.1));//报错

因为parseFloat()是专门用来处理字符串转换数字的,所以parseFloat处理非字符串和数字类型时输出NaN

[注意]parseFloat([数字或字符串])输出对应的数字

console.log(parseFloat(null),parseFloat(undefined));//NaN NaN  console.log(parseFloat(true),parseFloat(false));//NaN NaN  console.log(parseFloat([]),parseFloat([2.1]),parseFloat(['2.1px']));//NaN 2.1 2.1   console.log(parseFloat(''),parseFloat({}));//NaN NaN

继承的方法

Number类型是与数字值对应的包装类型 ,继承了引用类型的通用方法

valueOf():返回基本类型的数值

toString()和toLocaleString():返回字符串形式的数值

console.log(typeof 1.1.valueOf(),1.1.valueOf());//number 1.1  console.log(typeof 1.1.toString(),1.1.toString());//String '1.1'  console.log(typeof 1.1.toLocaleString(),1.1.toLocaleString());//String '1.1'
console.log(typeof 1.valueOf(),1.valueOf());//报错  console.log(typeof 1.toString(),1.toString());//报错  console.log(typeof 1.toLocaleString(),1.toLocaleString());//报错
var num = 1;  console.log(typeof num.valueOf(),num.valueOf());//number 1  console.log(typeof num.toString(),num.toString());//String '1'  console.log(typeof num.toLocaleString(),num.toLocaleString());//String '1'

[注意]可以为toString()方法传递一个表示基数的参数

var num = 10;  console.log(num.toString());//'10'  console.log(num.toString(2));//'1010'  console.log(num.toString(8));//'12'  console.log(num.toString(10));//'10'  console.log(num.toString(16));//'a'    

其他方法

toFixed()

按照指定的小数位返回数值四舍五入后的字符串表示(常用于处理货币值)

[注意]toFixed()里的参数只接受0-20,若不传参则相当于参数是0

var num = 10.456;  console.log(num.toFixed(2));//10.46  console.log(num.toFixed());//10  console.log(num.toFixed(-1));//报错

toExponential()

返回指数表示法(e表示法)的数值的字符串表示,参数表示转换后的小数位数

[注意]toExponential()里的参数只接受0-20,若不传参则相当于不针对小数进行四舍五入

var num = 10.456;  console.log(num.toExponential(2));//1.05e+1  console.log(num.toExponential());//1.0456e+1      console.log(num.toExponential(21));//报错

toPrecision()

接收一个参数 , 即表示数值的所有数字的位数(不包括指数部分) , 自动调用toFixed()或toExponential()

[注意]toFixed()里的参数只接受1-21,若不传参则不对原数字进行任何操作

var num = 10.1;  console.log(num.toPrecision(3));//10.1  console.log(num.toPrecision(2));//10          console.log(num.toPrecision(1));//1e+1  console.log(num.toPrecision());//10.1

来自: http://www.cnblogs.com/xiaohuochai/p/5098363.html