-
二进制和八进制表示法
ES6 提供了二进制和八进制数值的写法,分别用前缀 0b
(或0B
)和 0o
(或0O
)表示。若要将二进制与八进制转为十进制,
使用 Number 方法
注意:在ES5 中,在严格模式下,八进制不允许使用前缀 0 表示。
-
Number.isFinite(),Number.isNaN()
Number.isFinite() 用来检查一个数值是否为有限的而不是无限(Infinity)的。若参数类型不是数值,一律返回 false
Number.isNaN() 用来检查一个值是否为NaN,如果参数不是 NaN, Number.isNaN 一律返回 false。
与传统 isFinite() 和 isNaN() 方法会先调用 Number() 将非数值的值转为数值,再进行判断。
Number.isFinite() 对于非数值一律返回 false
Number.isNaN() 只有 值为NaN时才返回 true
isFinite(25) // true
isFinite("25") // true
Number.isFinite(25) // true
Number.isFinite("25") // false
isNaN(NaN) // true
isNaN("NaN") // true
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
-
Number.parseInt(),Number.parseFloat()
ES6 将全局方法 parseInt() 和 parseFloat() 移植到 Number 对象上,减少全局性方法,使得语言逐步模块化
Number.parseInt === parseInt // true
Number.parseFloat === parseFloat //true
//ES6 写法
Number.parseInt("12.34"); //12
Number.parseFloat("12.34") //12.34
Number.parseFloat("12.34##") //12.34
//ES5 写法
parseInt("12.34"); //12
parseFloat("12.34") //12.34
-
Number.isInteger()
Number.isInteger() 用来判断一个数值是否为整数。若对数据精度要求较高,不建议使用此方法判断。
注:在JavaScript 内部,整数和浮点数采用的是同样的存储方式,所以 25 和 25.0 视为同一个值。
Number.isInteger(25) // true
Number.isInteger(25.0) // true
/*如果参数不是数值,返回false*/
Number.isInteger(); //false
Number.isInteger('15'); // false
Number.isInteger(true) //false
Number.isInteger(null) //false
Number.isInteger(undefined) //false
/*注:JavaScript 数值存储为64位双精度格式,数值精度最多可以达到53 个二进制位,16个十进制位(小数点后最多16个数值,第 16 位数值以及后面的位数数值会被丢弃)
如果数值精度超过这个限度,第54 二进制位及后面的位数会被丢弃
*/
Number.isInteger(3.0000000000000002) // true
/*小数点后第16位以及16位往后数值被丢弃,所以造成返回结果为 true*/
/*注:若数值的绝对值小于 Number.MIN_VALUE(5E-324),即小于JavaScript 能够分辨的最小值,会被自动转为0*/
Number.isInteger(5E-324) // false
Number.isInteger(5E-325) // true
/*5E-325 小于 5E-324 ,值太小,会被自动转为 0 ,因此返回 true*/
-
Number.EPSILON === Math.pow(2,-52)
ES6 在Number对象上面新增了一个极小的常量 Number.EPSILON,用来表示1 与大于1的最小浮点数之间的差。
对于64位浮点数来说,大于1 的最小浮点数相当于二进制 1.00...001,小数点后面有连续51个零,这个值减去1 之后等于
是JavaScript 能够表示的最小精度,误差如果小于次之,即可认为不存在误差。实质是一个接受的最小误差范围。
Math.pow(2,-52)=== Number.EPSILON //true
因浮点数计算是不精确的,引入 Number.EPSILON 的目的在于在浮点数计算中,设置一个误差范围,小于这个误差范围,
即这两个浮点数相等。
0.1+0.2 //0.30000000000000004
0.1+0.2-0.3 //5.551115123125783e-17
0.1+0.2 === 0.3 //false
//设置两个浮点数的差小于Number.EPSILON(2的-52次方),则认为两个浮点数虎相等
0.1+0.2-0.3 < Number.EPSILON //true
function withErrorMargin(left,right){
return Math.abs(left-right) < Number.EPSILON ;
}
0.1+0.2 == 0.3 // false
withErrorMargin(0.1+0.2,0.3) //true
-
安全整数和Number.isSafeInteger()
JavaScript 能够表示的整数范围在 到
之间(不含两个端点,当超过这个范围后,则无法再精确表示这个值。
ES6 引入了 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 两个常量,用于表示范围的上下限。
Math.pow(2, 53) // 9007199254740992
9007199254740992 // 9007199254740992
9007199254740993 // 当值超出 2^53 后,值等于9007199254740992,并不精确
Math.pow(2, 53) === Math.pow(2, 53) + 1
// true
//使用 Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。
Number.MAX_SAFE_INTEGER === Math.pow(2,53)-1 // true 2^53-1 =9007199254740991
Number.MIN_SAFE_INTEGER === Math.pow(-2,53)+1 //true -2^53-(-1) = -9007199254740991
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER //true
Number.isSafeInteger() 用于判断一个整数是都落在这个范围之内。
注:当使用此函数验证运算结果是否落在安全整数的范围内,不仅要验证运算结果,同时还需验证参与运算的每个值。
若只验证运算结果是否为安全整数,但并不验证参与验算的值是否在安全整数范围内,验算结果很可能会计算错误。
Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false
Number.isSafeInteger(3) // true
Number.isSafeInteger(1.2) // false
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(9007199254740992) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false
// 同时验证两个运算数以及运算结果
function trusty(left,right,result){
if(Number.isSafeInteger(left) &&
Number.isSafeInteger(right) &&
Number.isSafeInteger(result)
){
return result;
}
throw new RangeError('Operation cannot be trusted!');
}
trusty(9007199254740993, 990, 9007199254740993 - 990)
// RangeError: Operation cannot be trusted!
trusty(1, 2, 3)
// 3
-
Math 函数的扩展方法
Math.trunc() 去除一个数的小数部分,返回整数部分。
对于非数值,Math.trunc() 内部使用 Number 方法将其转为数值。
对于空值以及无法截取整数的值,返回NaN
Math.trunc(0.7) // 0
Math.trunc('12.5') // 12
Math.trunc(null) // 0
Math.trunc(true) // 1
Math.trunc(false) // 0
Math.trunc(undefined) // NaN
Math.trunc() //NaN
Math.trunc('') // 0
Math.trunc('test') //NaN
Math.trunc(NaN) //NaN
//ES5 环境中,可以使用此代码进行模拟
Math.trunc = Math.trunc || function(x){
return x<0 ? Math.ceil(x): Math.floor(x);
}
Math.sign() 判断一个数到底是正数、负数、还是 0
对于非数值,会将其先转换为数值。无法转换为数值的,返回NaN。
返回值列举:
- 参数为正数,返回
+1
; - 参数为负数,返回
-1
; - 参数为 0,返回
0
; - 其他值,返回
NaN
。
Math.sign(5) // +1
Math.sign(-5) // -1
Math.sign(0) // 0
Math.sign(-0) // 0
Math.sign(NaN) //NaN
//对于非数值,会自动转为数值,对于无法转换值的值,返回NaN
Math.sign('') // 0
Math.sign(true) // +1
Math.sign(false) // 0
Math.sign(null) // 0
Math.sign('9') // +1
Math.sign('foo') // NaN
Math.sign() // NaN
Math.sign(undefined) // NaN
//ES5 中,可以用下面的代码模拟
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() 用于计算一个数的立方根
对于非数值,会将其转换为数值再计算,若无法转换,则返回NaN
Math.cbrt(8) // 2
Math.cbrt('8') // 2
Math.cbrt(null) // 0
Math.cbrt('hello') // NaN
//ES5 环境中代码模拟
Math.cbrt =Math.cbrt || function(x){
var y = Math.pow(Math.abs(x),1/3);
return x < 0 ? -y : y
}
Math.clz32() 将参数转为32位无符号整数的形式,然后返回这个32位值里面有多少个前导 0
对于小数,只考虑整数部分
对于空值或其他类型的值,Math.clz32方法会将它们先转为数值,然后再计算。
Math.clz32(0) //32 原因:0的二进制 0b0全为0,有32 位前导0
Math.clz32(1) //31 原因:1的二进制 0b1,只占1位,所以32位中有31个前导0
Math.clz32(3) //30 原因:3的二进制 0b11,占两位,所谓32位中有30个前导0
Math.clz32(1000) // 原因:1000的二进制形式 0b1111101000,一共有10 位,所以32位中有22个前导0
Math.clz32(0b01000000000000000000000000000000) // 1
Math.clz32(0b00100000000000000000000000000000) // 2
//对于小数,只考虑整数部分
Math.clz32(3.2) // 30
Math.clz32(3.9) // 30
//对于空值或其他类型的值,Math.clz32方法会将它们先转为数值,然后再计算。
Math.clz32() // 32
Math.clz32(NaN) // 32
Math.clz32(Infinity) // 32
Math.clz32(null) // 32
Math.clz32('foo') // 32
Math.clz32([]) // 32
Math.clz32({}) // 32
Math.clz32(true) // 31
Math.imul()返回两个数以32位带符号整数形式相乘的结果。返回的也是一个32位的带符号整数。可以返回正确的低位数值
在大多数情况下,Math.imul(a, b)
与a * b
的结果是相同的。即该方法等同于(a * b)|0
的效果(超过 32 位的部分溢出)
但当精度超过 后,JavaScript 无法保存额外的精度,会将低位值变为 0 。Math.imul() 方法可以返回正确的低位值。
Math.imul(2, 4) // 8
Math.imul(-1, 8) // -8
Math.imul(-2, -2) // 4
//返回正确的低位数值
(0x7fffffff * 0x7fffffff)|0 // 0
Math.imul(0x7fffffff, 0x7fffffff) // 1
Math.fround()返回一个数的32位单精度浮点数形式
主要用于将64位双精度浮点数转为32位单精度浮点数。
对于32位单精度浮点数,数值精度为24个二进制位。如果小数的精度超过24个二进制位,返回值就会不同于原值,否则返回值不变(即与64位双精度值一致)。
对于 NaN 和 Infinity,此方法会返回原值。
对于其他类型的非数值,会将其先转为数值,再返回单精度浮点数。
// 未丢失有效精度
Math.fround(1.125) // 1.125
/* 1.125 = 0b1.001 */
Math.fround(7.25) // 7.25
/* 7.25 = 0b 111.01 */
// 丢失精度
Math.fround(0.3) // 0.30000001192092896
/* 0.3 ==> 0.0100110011001100110011001100110011001100110011001101 小数精度超过24位二进制位
返回值会不同于原值,否则返回值不变(即与64位双精度值一致)*/
/*对于 NaN 和 Infinity,此方法返回原值。对于其它类型的非数值,Math.fround 方法会先将其转为数值,再返回单精度浮点数。*/
Math.fround(NaN) // NaN
Math.fround(Infinity) // Infinity
Math.fround('5') // 5
Math.fround(true) // 1
Math.fround(null) // 0
Math.fround([]) // 0
Math.fround({}) // NaN
//ES5 环境中可以用以下方法进行代码模拟
Math.fround = Math.fround || function(x){
return new Float32Array([x])[0];
}
Math.hypot() 返回所有参数的平方和的平方根
如果参数不是数值,Math.hypot
方法会将其转为数值。只要有一个参数无法转为数值,就会返回 NaN。
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
Math.hypot(NaN); // NaN
Math.hypot(3, 4, 'foo'); // NaN
Math.hypot(3, 4, '5'); // 7.0710678118654755
Math.hypot(-3); // 3
四个对数方法
Math.expm1(x) 返回 即 Math.exp(x) - 1
Math.log1p(x) 返回 1+x 的自然对数 ,即 Math.log(1 + x)
。如果x
小于-1,返回NaN
Math.log10(x) 返回以10 为底的 x 的对数,如果x 小于0,则返回NaN
Math.log2(x) 返回以 2 为底的 x 的对数,如果 x 小于 0,则返回NaN
-
指数运算符 **
当多个指数运算符连用时,从最右边开始计算
指数运算符可以与等号结合,形成一个新的赋值运算符( **= )
2 ** 2 // 4
2**3**2
==> 2 **(3**2)
==> 2 ** 9
==> 512
let b = 4
b **= 3
==> b = b**3
==> b = b*b*b = 64
-
BigInt 数据类型
BigInt(大整数)数据类型用于解决JavaScript对于 大于或等于2的1024次方的数值,以及精度超过53个二进制位(相当于16个十进制)的整数无法精确表示的问题。
BigInt 只用来表示整数,没有位数限制,任何位数的整数都可以精确表示。
BigInt 类型的数据必须添加后缀 n
BigInt 与普通整数属于两种类型的值,两者并不相等
BihInt 可以使用 负号(-),但不能使用(+)正号
const a = 1n;
const b = 2n;
const c = 2;
Number(a)+Number(c) //3
a+b // 3n
Number(a)+Number(b) //3
/*各种进制数据*/
0b1101n
0o777n
0xFFn
/*与普通整数并不相等*/
3 === 3n //false
/*只可以使用负号,正号不可以使用*/
-42n //正确
+42n //错误
1、可以使用Boolean()、Number()、String() 将BigInt数值转化为布尔值,数值,字符串类型。
转换为字符串后 BigInt数值后缀 n 会消失。
取反元素符也可以将BigInt 转为布尔值。
Boolean(0n) //false
Boolean(1n) //true
Number(1n) //1
String(1n) //"1"
!0n //true
!1n //false
2、BigInt 类型的 +、-、*、/、**运算度与Number类型行为一致,除法运算 / 会只保留整数部分,舍去小数部分。
9/5 //1.8
9n/5n //1n
3、BinInt 不能与普通数值进行混合运算
4、BigInt 与字符串混合运算时,会先转为字符串再进行运算。
5、比较运算符和相等运算符允许BigInt 与其他类型的值混合计算。
1n + 1.3 //"Cannot mix BigInt and other types, use explicit conversions"
'' + 123n // "123"
0n < 1 // true
0n < true // true
1n > false //true
0n == 0 // true
0n === 0 // false
0n == false // true