Appearance
数值扩展
二进制、八进制
二进制数(0b,0B),八进制数(0o,0O)
js
// 非严格模式
;(function () {
console.log(0o11 === 011)
})()(
// true
// 严格模式
function () {
'use strict'
console.log(0o11 === 011)
}
)() // Uncaught SyntaxError: Octal literals are not allowed in strict mode.二进制、八进制转十进制
js
Number('0b111') // 7
Number('0o10') // 8数值分隔符
ES2021 - 允许使用下划线分割字符
js
let budget = 1_000_000_000_000
budget === 10 ** 12 // true分割数量可以随意,小数科学计数法也适用
js
12345_00 === 1_234_500 // true
// 小数
0.000_001
// 科学计数法
1e10_000下划线位置需满足以下条件
- 不能在最前或最后
- 不能连续放置
- 小数点的前后不能有分隔符
- 科学计数法,表示指数的
e或E前后不能有分隔符 - 进制前缀前后不能有分隔符
js
// 全部报错
_1464301
1464301_
123__456
3_.141
3._141
1_e12
1e_12
0_b111111000
0b_111111000只是书写便利,没有实质意义。也不能进行用于解析。
js
let num = 12_345
num // 12345
num.toString() // 12345
Number(123_456) // 123456
Number('123_456') // NaN
parseInt('123_456') // 123Number 对象
目的:减少全局方法,语言逐渐模块化
Number.isFinite()
Number.isFinite():数值是否为有限的(finite),即不是 Infinit、NaN。参数不为 Number,返回 false
全局方法中的 isFinite,会将参数向 Number 进行隐式转化
js
Number.isFinite(15) // true
Number.isFinite(0.8) // true
Number.isFinite(NaN) // false
Number.isFinite(Infinity) // false
Number.isFinite(-Infinity) // false
Number.isFinite('foo') // false
Number.isFinite('15') // false
Number.isFinite(true) // false
isFinite('15') // trueNumber.isNaN()
Number.isNaN():检测值是否为 NaN,参数类型不是 NaN,返回 false
全局方法中 isNaN 也会向 Number 隐式转换
js
Number.isNaN(NaN) // true
Number.isNaN('NaN') // false
Number.isNaN(1) // false
isNaN(NaN) // true
isNaN('NaN') // trueNumber.parseInt()、Number.parseFloat()
Number.parseInt(),Number.parseFloat()与全局方法行为一致。
js
// ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45
// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45Number.isInteger()
Number.isInteger():用来判断一个数值是否为整数,参数类型不是 Number 直接返回 false
整数和浮点数采用同样存储方法,25 和 25.0 视为同值
js
Number.isInteger(25) // true
Number.isInteger(25.0) // trueJavaScript 采用 IEEE 754 标准,数值存储为64 位双精度格式,超过精度存在误判
- 数值精度最高:可以达到 53 个二进制位(1 个隐藏位与 52 个有效位) - 也就是小数点后 16 个十进制位。16 位将会舍去
- 数值精度最低:
Number.MIN_VALUE(5E-324)
js
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(3.0000000000000002) // true
Number.isInteger(5e-325) // true对于高精度,isInteger 会存在误判
Number.EPSILON
Number.EPSILON:极小常量(最小误差值),表示 1 与大于 1 的最小浮点数之间的差。误差小于此值,可以认为没有误差
对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的1.00..001,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的 -52 次方(0.00..001)。
js
Number.EPSILON === Math.pow(2, -52)
// true
Number.EPSILON
// 2.220446049250313e-16
Number.EPSILON.toFixed(20)
// "0.00000000000000022204"问题:浮点数计算不精确
js
0.1 + 0.2
// 0.30000000000000004
0.1 + 0.2 - 0.3
// 5.551115123125783e-17
;(5.551115123125783e-17).toFixed(20)
// '0.00000000000000005551'例子:设置误差范围为 2^-50
js
function withinErrorMargin(left, right) {
return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2)
}
0.1 + 0.2 === 0.3 // false
withinErrorMargin(0.1 + 0.2, 0.3) // true
1.1 + 1.3 === 2.4 // false
withinErrorMargin(1.1 + 1.3, 2.4) // trueNumber.isSafeInteger()
整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个值
Number.isSafeInteger():判断整数是否在-2^53到2^53之间
js
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // 9007199254740991
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER // -9007199254740991验证运算结果是否落在安全整数的范围内,不要只验证运算结果,而要同时验证参与运算的每个值。
js
Number.isSafeInteger(9007199254740993)
// false
Number.isSafeInteger(990)
// true
Number.isSafeInteger(9007199254740993 - 990) // 超出了精度范围,以9007199254740992的形式储存
// true
9007199254740993 - 990
// 返回结果 9007199254740002
// 正确结果 9007199254740003Math 对象
Math.trunc()
Math.trunc():去除一个数的小数部分,返回整数部分。
规则
非数值,先转换为数值
空值和无法截取整数,返回 NaN
js
Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0polyfill
js
Math.trunc =
Math.trunc ||
function (x) {
return x < 0 ? Math.ceil(x) : Math.floor(x)
}Math.sign()
Math.sign():判断一个数到底是正数、负数、还是零。
规则
- 非数值,先转换为数值
js
Math.sign(-5) // 负数 -1
Math.sign(5) // 正数 +1
Math.sign(0) // 零 +0
Math.sign(-0) // 负零 -0
Math.sign(NaN) // 其他值 NaNpoyfill
js
Math.sign =
Math.sign ||
function (x) {
x = +x // convert to a number
if (x === 0 || isNaN(x)) {
return x
}
return x > 0 ? 1 : -1
}其他
| 方法 | |
|---|---|
| Math.cbrt | 计算一个数的立方根 |
| Math.clz32 | 将参数转为 32 位无符号整数的形式 |
| Math.imul | 两个数以 32 位带符号整数形式相乘的结果 |
| Math.fround | 一个数的 32 位单精度浮点数形式 |
| Math.hypot | 返回所有参数的平方和的平方根 |
| 对数方法 | |
| Math.expm1 | 返回 e^x - 1 |
| Math.log1p | 1 + x的自然对数 |
| Math.log10 | 以 10 为底的x的对数 |
| Math.log2 | 以 2 为底的x的对数 |
| 双曲线函数 | |
| Math.sinh | 双曲正弦 |
| Math.cosh | 双曲余弦 |
| Math.tanh | 双曲正切 |
| Math.asinh | 反双曲正弦 |
| Math.acosh | 反双曲余弦 |
| Math.atanh | 反双曲正切 |
指数运算符
ES2016 - 指数运算符(**),从右向左结合
js
// 相当于 2 ** (3 ** 2)
2 ** (3 ** 2)BigInt 数据类型
问题:JavaScript 所有数字都保存成 64 位浮点数,会产生以下两个问题
- 数值的精度只能到 53 个二进制位(16 个十进制)
- 大于或等于 2 的 1024 次方的值,无法表示(返回 Infinity)
BigInt :可以精确表示任何位数的整数(后缀为n)
- BigInt ,普通整数是两种值
js
42n === 42 // falsetypeof运算符:BigInt 类型数据返回bigint
js
typeof 123n // 'bigint'- 可以用
-不能用+
js
;-42n + // 正确
42n // 报错BigInt 函数
BigInt()构造函数
- 必须有参数
- 参数必须可以正常转为数值(整数)
js
new BigInt() // TypeError
BigInt(undefined) //TypeError
BigInt(null) // TypeError
BigInt('123n') // SyntaxError
BigInt('abc') // SyntaxError
BigInt(1.5) // RangeError
BigInt('1.5') // SyntaxError字符串
123n无法解析成 Number 类型,所以报错
BigInt.asUintN(width, BigInt): 给定的 BigInt 转为 0 到 2^width-1^ 之间对应的值。
BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2^width-1^ 到 2^width-1^-1 之间对应的值。
js
const max = 2n ** (64n - 1n) - 1n
BigInt.asIntN(64, max)
// 9223372036854775807n
BigInt.asIntN(64, max + 1n)
// -9223372036854775808n
BigInt.asUintN(64, max + 1n)
// 9223372036854775808nmax 为 64 位 BigInt 能表示的最大值。+1 后,新增一位为符号位
BigInt.parseInt(string[, radix]):将一个字符串转换成指定进制的 BigInt
js
// Number.parseInt() 与 BigInt.parseInt() 的对比
Number.parseInt('9007199254740993', 10)
// 9007199254740992
BigInt.parseInt('9007199254740993', 10)
// 9007199254740993n转换规则
js
Boolean(0n) // false
Boolean(1n) // true
Number(1n) // 1
String(1n) // "1"
!0n // true
!1n // false数学运算
+、-、*、**:与 Number 类型的行为一致
/:舍去小数部分,返回一个整数
js
9n / 5n // 1n注意事项
- BigInt 不能用于不带符号的右移位运算符
>>>(BigInt 总是带符号,导致无符号运算无意义) - BigInt 不能与普通数值混合运算(无论是返回
BigInt或Number都会丢失精度)
js
2n ** 53n + 1n + 0.51n | 0 也会报错
其他运算
BigInt 对应的布尔值,与 Number 类型一致,即0n会转为false,其他值转为true
比较运算符(比如>)和相等运算符(==)允许 BigInt 与其他类型的值混合计算,因为这样做不会损失精度。
js
0n < 1 // true
0n < true // true
0n == 0 // true
0n == false // true
0n === 0 // falseBigInt 与字符串混合运算时,会先转为字符串,再进行运算。
js
'' + 123n // "123"