一. 基本数据类型中的数值
const a = 1;
const b = 5.20;
const c = 0xab;
数字有很多类型,按照数字精度可以分为整数(int),单精度(float),双精度(double );按照数字的表示方法可以分为二进制(Binary),八进制(Octal),十进制(decimal system),十六进制(Hexadecimal)。
但是在Js中,所有的数字统一使用Number来表示。 体现JS弱类型语言的特点:类型细分不明显。
typeof a ; //Number
1.1 数值的进制
在JavaScript中对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制。
- 十进制 —— 88,64,2…;
- 八进制(0o / 0O)—— 0o72,0O465…;
- 十六进制(0x / 0X)—— 0xfff,0x7b3,0Xccc…;
- 二进制(0b / 0B) —— 0b11101,0B1010111…;
如果八进制、十六进制、二进制的数值里面,出现不属于该进制的数字,就会报错。
0xzz // 报错
0o88 // 报错
0b22 // 报错
1.2 特殊数值
JavaScript 中还提供了几个特殊的数值。比如:
1.2.1 正零(+0)和负零(-0)
之前说过,JavaScript 中表示数字的64位浮点数之中,有一个二进制位是符号位。这意味着,任何一个数都有一个对应的负值,就连0也不例外。
-0 === +0 // true
0 === -0 // true
0 === +0 // true
在绝大多数的情况下,正零(+0)和负零(-0)是没有区别的。唯有在做分母的时候,两者结果不同:
(1 / +0) === (1 / -0) // false
1 / +0 // +Infinity
1 / -0 // -Infinity
1.2.2 NaN
NaN是Not a Number的缩写,表示非数字。常见于字符串和数字运算的结果。
1 - 'a' // NaN
0 / 0 // NaN
需要注意的是,NaN不是独立的数据类型,而是一个特殊数值,它的数据类型依然属于Number。
typeof NaN // Number
NaN不等于任何值,包括它本身。所以NaN也是唯一一个和自身不严格相等的值。
NaN === NaN // false
因此NaN在作为数组元素时,并不能被indexOf()
方法找到。
[NaN].indexOf(NaN) // -1
NaN在布尔运算时被当作false。
Boolean(NaN) // false
NaN与任何数(包括它自己)的运算,得到的都是NaN。
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
1.2.3 无穷(+Infinity / -Infinity)
Infinity表示“无穷”,本身有正负之分。
Infinity === -Infinity // false
1 / -0 // -Infinity
-1 / -0 // Infinity
有关Infinity的运算,都符合无穷的数学计算规则。
5 + Infinity // Infinity
5 - Infinity // -Infinity
0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity
Infinity与null计算时,null会转成0,等同于与0的计算。
null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity
Infinity与undefined计算,返回的都是NaN。
undefined + Infinity // NaN
undefined - Infinity // NaN
undefined * Infinity // NaN
undefined / Infinity // NaN
Infinity / undefined // NaN
1.3 与数值相关的全局方法
1.3.1 parseInt()
parseInt方法用于将字符串转为整数。
parseInt('123') // 123
parseInt(' 81') // 81
parseInt(1.23) // 1
字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。正负号开头的除外。
parseInt('5c20') // 5
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15px') // 15
如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
如果字符串以进制前导开头,parseInt会将其按照十对应的进制数解析。
parseInt('0x10') // 16
parseInt('011') // 11
parseInt还有一个重要的作用就是:进制转换。它还可以接受第二个参数(2 =< n <=36)来指定要转换为的进制数。
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
如果字符串包含对于指定进制无意义的字符,则从最高位开始,只返回可以转换的数值。如果最高位无法转换,则直接返回NaN。
parseInt('1546', 2) // 1
parseInt('546', 2) // NaN
1.3.2 parseFloat()
parseFloat方法用于将一个字符串转为浮点数。
parseFloat('3.14') // 3.14
parseFloat()的一些具体规则和之前的parseInt()差不多。相对于Number函数它们的转换结果会有很多不同:
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
1.3.3 isNaN()
isNaN方法可以用来判断一个值是否为NaN。
isNaN(NaN) // true
isNaN(123) // false
但是,isNaN只对数值有效,如果传入其他值,会被先转成数值。比如,传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别引起注意。也就是说,isNaN为true的值,有可能不是NaN,而是一个字符串。
isNaN('Hello') // true
// 相当于
isNaN(Number('Hello')) // true
所以就会出现一些看似很奇怪的结果:
isNaN({}) // true
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
所以判断NaN更可靠的方法是,利用NaN为唯一不等于自身的值的这个特点。
function myIsNaN(value) {
return value !== value;
}
1.3.4 isFinite()
isFinite方法返回一个布尔值,表示某个值是否为正常的数值。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
isFinite(null) // true
isFinite(-1) // true
除了Infinity、-Infinity、NaN和undefined这几个值会返回false,isFinite对于其他的数值都会返回true。
二. Number对象
Number对象是数值对应的包装对象,可以作为构造函数使用,也可以作为工具函数使用。
2.1 构造函数
作为构造函数时,它用于生成值为数值的对象。所以typeof运算符的结果是object。
var n = new Number(1);
typeof n // "object"
2.2 工具函数
作为工具函数时,它可以将任何类型的值转为数值。
Number(true) // 1
2.3 静态属性
这些属性基本都不常用,了解即可。这里我就只列举三个:
- Number.NaN —— 表示非数值,指向NaN。
- Number.MAX_SAFE_INTEGER —— 表示能够精确表示的最大整数,即9007199254740991。
- Number.MIN_SAFE_INTEGER —— 表示能够精确表示的最小整数,即-9007199254740991。
Number.NaN // NaN
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MIN_SAFE_INTEGER // -9007199254740991
三. Number.prototype
Number对象共有5个实例方法,都跟数值的格式转化有关。
3.1 Number.prototype.toString()
Number原型的toString方法,用来将一个数值转为字符串形式。它还可以接受一个参数,表示输出的进制。如果省略这个参数,默认将数值先转为十进制,再输出字符串。
(10).toString() // "10"
(10).toString(2) // "1010"
(10).toString(8) // "12"
(10).toString(16) // "a"
要注意整数数值不能直接调用toString()方法:
10.toString()
// SyntaxError: Unexpected token ILLEGAL
除了用上述括号的形式,还可以用两个点的形式,空格,小数或者方括号运算符的形式:
(10).toString(2) // "1010"
10..toString(2) // "1010"
10 .toString(2) // "1010"
10.0.toString(2) // "1010"
10['toString'](2) // "1010"
与上述两个点的方式同理,所以对于浮点数是可以直接调用的:
10.5.toString(2) // "1010.1"
3.2 Number.prototype.toFixed()
toFixed()方法先将一个数转为指定位数的小数,然后返回这个小数对应的字符串。
(10).toFixed(2) // "10.00"
10.005.toFixed(2) // "10.01"
要注意的是,由于浮点数的原因,四舍五入是不稳定的。
(10.055).toFixed(2) // 10.05
(10.045).toFixed(2) // 10.04
(10.035).toFixed(2) // 10.04
(10.025).toFixed(2) // 10.03
(10.015).toFixed(2) // 10.02
(10.005).toFixed(2) // 10.01
3.3 Number.prototype.toExponential()
toExponential方法用于将一个数转为科学计数法形式。
(1234).toExponential() // "1.234e+3"
(1234).toExponential(1) // "1.2e+3"
(1234).toExponential(2) // "1.23e+3"
3.4 Number.prototype.toPrecision()
Number.prototype.toPrecision()方法用于将一个数转为指定位数的有效数字。
(12.34).toPrecision(1) // "1e+1"
(12.34).toPrecision(2) // "12"
(12.34).toPrecision(3) // "12.3"
(12.34).toPrecision(4) // "12.34"
(12.34).toPrecision(5) // "12.340"
3.5 Number.prototype.toLocaleString()
toLocaleString()
这个方法作用是把数字转换为字符串并使用三位分节法进行显示。如果是浮点数,还会进行四舍五入并保留三位小数的操作。
1384125862..toLocaleString() // 1,384,125,862
1234567890.125462.toLocaleString() // 1,234,567,890.125
另外toLocaleString()
方法接受一个地区码作为参数,返回一个字符串,表示当前数字在该地区的当地书写形式。
(123).toLocaleString('zh-Hans-CN-u-nu-hanidec')
// "一二三"
该方法还可以接受第二个参数配置对象,用来定制指定用途的返回字符串。该对象的style属性指定输出样式,默认值是decimal,表示输出十进制形式。如果值为percent,表示输出百分数。
(123).toLocaleString('zh-Hans-CN', { style: 'percent' })
// "12,300%"
如果style属性的值为currency,则可以搭配currency属性,输出指定格式的货币字符串形式。
(123).toLocaleString('zh-Hans-CN', { style: 'currency', currency: 'CNY' })
// "¥123.00"
(123).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
// "123,00 €"
(123).toLocaleString('en-US', { style: 'currency', currency: 'USD' })
// "$123.00"