数值
Number.isFinite( arg ) // 判断 arg 是否是有限数值, 如果不是数值或是 NaN 或 +-Infinite 都返回false
Number.isNaN( arg ) // 判断 arg 是否是数值类型,
以上两种方式不同于传统方法 isFinite() 和 isNaN(), 传统方法是先调用 Number() 方法将参数转换成数值类型再判断,以上两种方法是直接进行判断。
1 isFinite(25) // true 2 isFinite("25") // true 3 Number.isFinite(25) // true 4 Number.isFinite("25") // false 5 6 isNaN(NaN) // true 7 isNaN("NaN") // true 8 Number.isNaN(NaN) // true 9 Number.isNaN("NaN") // false 10 Number.isNaN(1) // false
Number.parseInt() 和 Number.parseFloat()
以上两种方法同传统的全局方法 parseInt() 和 parseFloat(), ES6 新增的目的就是为了减少全局方法,是语言模块化。
1 // 全局方法的写法 2 parseInt('12.34') // 12 3 parseFloat('123.45#') // 123.45 4 5 // ES6的写法 6 Number.parseInt('12.34') // 12 7 Number.parseFloat('123.45#') // 123.45 8 9 // 两种方法是一样的 10 Number.parseInt === parseInt // true 11 Number.parseFloat === parseFloat // true
Number.isInteger() // 判断是否是整数
1 Number.isInteget(11); // true 2 Number.isInteget(11.0); // true 3 // 整数和浮点的储存类型一样, 11.0 和 11 被视为同一个值 4 var num = 11.0 5 console.log(num) // 11 6 7 // 如果参数不是整数就返回false,并不会先转换成数值类型再判断 8 Number.isInteger() // false 9 Number.isInteger(null) // false 10 Number.isInteger('15') // false 11 Number.isInteger(true) // false 12 13 // JavaScript 采用的是IEEE745标准,数值精度醉倒是53位,多余的会被省略 14 Number.isInteger(3.0000000000000002) // true 15 16 // 同时如果一个数小于5E-324,那么这个方法就是是这个数为0 17 Number.isInteger(5E-324) // false 18 Number.isInteger(5E-325) // true
当数值位数过多,会数值过小是,这个方法会将原数值进行改变,因此,当对数据要求精度过高时,并不适用这个方法。
安全整数 和 Number.isSafeInteger()
JavaScript 只能精确到 (-2^53, 2^53),当不在这个区间内,则无法精确表达这个值,即: Math.pow(2, 53) === Math.pow(2, 53) + 1。
ES6 引入 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 这两个变量来表示最大最小安全整数
即: Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 === -Number.MIN_SAFE_INTEGER
Number.isSafeInterger() 则是判断一个数是否在安全整数的区间
实际使用这个函数时,需要注意。验证运算结果是否落在安全整数的范围内,不要只验证运算结果,而要同时验证参与运算的每个值。
Number.isSafeInteger(9007199254740993) // false Number.isSafeInteger(990) // true Number.isSafeInteger(9007199254740993 - 990) // true 9007199254740993 - 990 // 返回结果 9007199254740002 // 正确答案应该是 9007199254740003
Math 对象的扩展
Math.trunc() // 取出数值的小数部分, 如果非数则会先转换成数值,如果转换后还是非数则返回NAN
1 Math.trunc(4.1) // 4 2 Math.trunc(-4.1) // -4 3 Math.trunc(-0.1234) // -0 4 5 // 非数 6 Math.trunc('123.456') // 123 7 Math.trunc(true) //1 8 Math.trunc(false) // 0 9 Math.trunc(null) // 0 10 Math.trunc(NaN); // NaN 11 Math.trunc('foo'); // NaN 12 Math.trunc(undefined) // NaN 13 14 // 如果环境没有部署这个方法,则可以用以下代码模拟 15 Math.trunc = Math.trunc || function(x) { 16 return x < 0 ? Math.ceil(x) : Math.floor(x); 17 };
Math.sign() // 判断一个数是整数,负数,零,返回+-1,+-0,NAN。 对于非数会先转成数或返回NAN
Math.sign(-5) // -1 Math.sign(5) // +1 Math.sign(0) // +0 Math.sign(-0) // -0 Math.sign(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 // 模拟 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.cbrt(-1) // -1 Math.cbrt(1) // 1 Math.cbrt(2) // 1.2599210498948734 // 非数 Math.cbrt('8') // 2 Math.cbrt('abc') // NaN // 模拟 Math.cbrt = Math.cbrt || function(x) { var y = Math.pow(Math.abs(x), 1/3); return x < 0 ? -y : y; };
Math.clz32() // 将参数转成32位无符号整数形式,然后返回有多少个先导0
1 Math.clz32(0) // 32 2 Math.clz32(1) // 31 3 Math.clz32(1000) // 22 4 Math.clz32(0b01000000000000000000000000000000) // 1 5 Math.clz32(0b00100000000000000000000000000000) // 2 6 7 // 左移运算符(<<)与Math.clz32方法直接相关。 8 Math.clz32(0) // 32 9 Math.clz32(1) // 31 10 Math.clz32(1 << 1) // 30 11 Math.clz32(1 << 2) // 29 12 Math.clz32(1 << 29) // 2 13 14 // Math.clz32() 只考虑整数部分,不考虑小数 15 Math.clz32(6.1) // 29 16 Math.clz32(6.9) // 29 17 18 //对于空值或其他类型的值,Math.clz32方法会将它们先转为数值,然后再计算。 19 Math.clz32() // 32 20 Math.clz32(NaN) // 32 21 Math.clz32(Infinity) // 32 22 Math.clz32(null) // 32 23 Math.clz32('foo') // 32 24 Math.clz32([]) // 32 25 Math.clz32({}) // 32 26 Math.clz32(true) // 31
Math.imul() // 返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。
1 Math.imul(-1, 8) // -8 2 Math.imul(-2, -2) // 4 3 4 // 在32位内,乘法计算与Math.imul()一直 5 // 但当数值大于32位是,正常的乘法计算,并不能进行精确计算 6 7 (0x7fffffff * 0x7fffffff)|0 // 0 8 9 Math.imul(0x7fffffff, 0x7fffffff) // 1
Math.hypot() // 返回参数平方和的平方根, 如果参数非数则转成数,转不出则返回NAN
Math.hypot(3, 4); // 5 Math.hypot(3, '4'); // 5 Math.hypot(); // 0 Math.hypot(NaN); // NaN Math.hypot(3, 'foo'); // NaN Math.hypot(-3); // 3
指数运算符( ** )
2 ** 2 // 4 2 ** 3 // 8
注意,多个指数运算符连用时,是从右向左的, 同时要注意指数运算符与赋值运算符一起使用时,不要混淆
// 相当于 2 ** (3 ** 2) 2 ** 3 ** 2 // 512
let a = 2;
a **= 3;
// a = a * a * a
BigInt 数据类型(ES2020) // 为了解决大位数无法精确表示,ES2020 引入的新数据类型(大整数),BigInt 只能是整数,没有位数限制,可以精确计算
1、为了和数值类型进行区分,BigInt 数据要加后缀 n
1 const a = 2172141653n; 2 const b = 15346349309n; 3 4 // BigInt 可以保持精度 5 a * b // 33334444555566667777n 6 7 // 普通整数无法保持精度 8 Number(a) * Number(b) // 33334444555566670000
2、BigInt 与 普通数据是不同的,二者并不相等 // 12n !== 12
3、typeof 运算符对 BigInt 数据返回的是 bigInt
typeof 123n // 'bigint'
4、BigInt 数据可以使用负号( - ),但是不能使用正号( + )
5、 JavaScript 之前是不能表示70的阶乘的,因为超出了精度,但是BigInt 是可以的
BigInt 对象 // JavaScript 原生提供BigInt
对象,可以用作构造函数生成 BigInt 类型的数值。转换规则基本与Number()
一致,将其他类型的值转为 BigInt。
BigInt(123) // 123n BigInt('123') // 123n BigInt(false) // 0n BigInt(true) // 1n
BigInt()
构造函数必须有参数,而且参数必须可以正常转为数值,同时还必须是整数,否则就会报错,下面的用法都会报错。
1 new BigInt() // TypeError 2 BigInt(undefined) //TypeError 3 BigInt(null) // TypeError 4 BigInt('123n') // SyntaxError 5 BigInt('abc') // SyntaxError 6 7 BigInt(1.5) // RangeError 8 BigInt('1.5') // SyntaxError
BigInt 也可以使用String(),Number(),Boolean()转换成相对应的类型,同时也可以用取反运算符( ! ) 转换成布尔值
1 Boolean(0n) // false 2 Boolean(1n) // true 3 Number(1n) // 1 4 String(1n) // "1" 转换成字符串时,n会省略 5 6 !0n // true 7 !1n // false
BigInt的数学运算同普通数值类型基本一样( +, -, *, / ) ,需要注意的是,使用除法时,会自动省略小数部分
与普通数值数学运算不同的是,不能使用一元求正运算符( + )和不带符号的右移位运算符( >>> ),
BigInt 不能和普通数值进行运算,因为可能导致精度丢失
BigInt 与字符串进行运算时,会先转化成字符串在运算,// "" + 12n === "12"
BigInt 能够使用比较运算符( >, <) 和相等运算符,与其他类型数据进行比较, 主要是因为这样的计算不会使BigInt 丢失精度
1 0n < 1 // true 2 0n < true // true 3 0n == 0 // true 4 0n == false // true 5 0n === 0 // false
-----不生产代码,只是代码的搬运工