乐趣区

关于es6:7数值的扩展

1. 二进制八进制

二进制: 前缀 0b:0b111110111 === 503
八进制: 前缀 0o:0o767 === 503

2.Number.isFinite(),Number.isNaN()

Number.isFinite(): 查看数值是否为无限的,Infinity 和非数值类型都返回 false

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

Number.isNaN(): 查看数值是否为 NaN, 参数类型不是 NaN 返回 false

Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true

区别于传统的 isFinite()和 isNaN()
isFinite()和 isNaN()会先调用 Number(), 转为数字, 再判断
Number.isFinite(),Number.isNaN() 只对数字无效, 不转化

3.Number.parseInt(),Number.parseFloat()

ES6 将全局办法 parseInt()和 parseFloat(),移植到 Number 对象下面,行为齐全放弃不变。
这样做的目标,是逐渐缩小全局性办法,使得语言逐渐模块化。

Number.parseInt === parseInt // true
Number.parseFloat === parseFloat // true

4.Number.isInteger()

Number.isInteger(): 判断一个数是否为整数, 非数值和浮点数返回 false
(js 外部, 整数和浮点数采纳同样的贮存办法, 所以 25.0 等同于 25)
留神 :
1. 因为 JavaScript 采纳 IEEE 754 规范,数值存储为 64 位双精度格局,
数值精度最多能够达到 53 个二进制位(1 个暗藏位与 52 个无效位)。
如果数值的精度超过这个限度,第 54 位及前面的位就会被抛弃,
这种状况下,Number.isInteger 可能会误判。
2. 如果一个数值的绝对值小于 Number.MIN_VALUE(5E-324),
即小于 JavaScript 可能分辨的最小值,会被主动转为 0。
这时,Number.isInteger 也会误判。

Number.isInteger(3.0000000000000002) // true

所以 : 如果对数据精度的要求较高,不倡议应用 Number.isInteger() 判断一个数值是否为整数。

5.Number.EPSILON

js 能示意的最小精度. 目标在于为浮点数计算,设置一个可能承受的误差范畴。

误差范畴设为 2 的 -50 次方(即 Number.EPSILON * Math.pow(2, 2)),即如果两个浮点数的差小于这个值,咱们就认为这两个浮点数相等。0.1 + 0.2
// 0.30000000000000004
0.1 + 0.2 - 0.3
// 5.551115123125783e-17
5.551115123125783e-17.toFixed(20)
// '0.00000000000000005551'
5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2)
// true

6.Number.isSafeInteger()

Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER: 用来示意整数范畴在 -2^53 到 2^53 的上上限
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

7.Math 对象的扩大

Math.trunc()去除小数, 返回整数

Math.trunc(4.9) // 4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0

非数值先进行转化

Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0

空值和无奈截取整数的值, 返回 NaN

Math.trunc("abc123") //NaN
Math.trunc(NaN); //NaN
Math.trunc(); //NaN
Math.trunc(undefined) //NaN

es5 模仿:

Math.trunc = Math.trunc||function(x){return x<0?Math.ceil(x):Math.floor(x)
}
Math.ceil()为向上取整, 小数局部为 0 时数字放弃不变
Math.floor()为向下取整, 小数局部为 0 时数字放弃不变

Math.sign()

判断一个数是负数, 正数, 还是 0, 非数值会转化成数值
返回 5 个值:
参数为负数: 返回 +1
参数为正数: 返回 -1
参数为 0: 返回 0
参数为 -0: 返回 -0
参数为其余: 返回 NaN
es5 模仿:

Math.sign = Math.sign||function(x){
    x = +x
    if(x === 0||isNaN(x)){return x}
    return x>0?1:-1
}

Math.cbrt()

计算立方根, 非数值会转化成数值
es5 模仿:

Math.cbrt=Math.cbrt||function(x){var y = Math.pow(Math.abs(x),1/3)
    return x<0?-y:y
}
Math.pow(x,y)=>x 的 y 次幂
Math.abs(x)=> 绝对值

Math.clz32()

将参数转化为 32 位无符号整数, 返回这个 32 位值里多少个前导 0

Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1000) // 22
Math.clz32(0b01000000000000000000000000000000) // 1
Math.clz32(0b00100000000000000000000000000000) // 2
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.clz32(3.2) // 30
Math.clz32(3.9) // 30

Math.imul()

针对于很大数的乘法, 返回 2 个数以 32 位带符号整数相乘的后果

(0x7fffffff * 0x7fffffff)|0 // 0
下面这个乘法算式,返回后果为 0。然而因为这两个二进制数的最低位都是 1,所以这个后果必定是不正确的,因为依据二进制乘法,计算结果的二进制最低位应该也是 1。这个谬误就是因为它们的乘积超过了 2 的 53 次方,JavaScript 无奈保留额定的精度,就把低位的值都变成了 0。Math.imul 办法能够返回正确的值 1。Math.imul(0x7fffffff, 0x7fffffff) // 1

Math.fround()

返回一个数的 32 位单精度浮点数模式。
Math.fround 办法的次要作用,是将 64 位双精度浮点数转为 32 位单精度浮点数。如果小数的精度超过 24 个二进制位,返回值就会不同于原值,否则返回值不变(即与 64 位双精度值统一)。

// 未失落无效精度
Math.fround(1.125) // 1.125
Math.fround(7.25)  // 7.25

// 失落精度
Math.fround(0.3)   // 0.30000001192092896
Math.fround(0.7)   // 0.699999988079071
Math.fround(1.0000000123) // 1

es5:

Math.fround = Math.fround || function (x) {return new Float32Array([x])[0];
};

Math.hypot()

返回所有参数的平方和的平方根, 非数值会转化成数值

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 的平方 + 4 的平方 = 5 的平方
无奈转为数值, 返回 NaN

对数办法

Math.expm1()
Math.log1p()
Math.log10()
Math.log2()
详情

双曲函数办法

Math.sinh(x) 返回 x 的双曲正弦(hyperbolic sine)
Math.cosh(x) 返回 x 的双曲余弦(hyperbolic cosine)
Math.tanh(x) 返回 x 的双曲正切(hyperbolic tangent)
Math.asinh(x) 返回 x 的反双曲正弦(inverse hyperbolic sine)
Math.acosh(x) 返回 x 的反双曲余弦(inverse hyperbolic cosine)
Math.atanh(x) 返回 x 的反双曲正切(inverse hyperbolic tangent)
详情

8. 指数运算符 **

2 ** 2 // 4
2 ** 3 // 8

这个运算符的一个特点是右联合,而不是常见的左联合

// 相当于 2 ** (3 ** 2) =>2**9 
2 ** 3 ** 2  // 512

新赋值运算符:**=

let a = 1.5
a **= 2   //a=2.25

let b = 4;
b **= 3;  //b = 64

9.BigInt

es 第 8 种数据类型, 只用来示意整数, 没有位数限度, 不等于一般整数, 要加后缀 n,typeof 返回 bigint
解决:
1. 超过 53 个二进制位的数值, 无奈放弃精度.
2. 超过 2 的 1024 次方的数值, 无奈示意.

1234 // 一般整数
1234n // BigInt

// BigInt 的运算
1n + 2n // 3n

42n === 42 // false

typeof 123n // 'bigint'

-42n // 正确
+42n // 报错

let p = 1n;
for (let i = 1n; i <= 70n; i++) {p *= i;}
console.log(p); // 11978571...00000000n

BigInt 对象

js 提供原生 BigInt 对象, 能够用作构造函数生成 BigInt 类型的数值, 能够将其余类型转为 BigInt

BigInt(123) //123n
BigInt('123') // 123n
BigInt(false) // 0n
BigInt(true) // 1n

BigInt()构造函数必须有参数, 且能转为数值, 否则报错

new BigInt() // TypeError
BigInt(undefined) //TypeError
BigInt(null) // TypeError
BigInt('123n') // SyntaxError  // 无奈转为 number 类型
BigInt('abc') // SyntaxError
BigInt(1.5) // RangeError  // 小数也会报错
BigInt('1.5') // SyntaxError  // 小数也会报错

BigInt 对象继承了 Object 对象的 2 个实例办法

  • BigInt.prototype.toString()
  • BigInt.prototype.valueOf()

BigInt 对象继承了 Number 对象的 1 个实例办法

  • BigInt.prototype.toLocalString()

三个静态方法

  • BigInt.asUintN(width, BigInt):给定的 BigInt 转为 0 到 2width – 1 之间对应的值。
  • BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2width – 1 到 2width – 1 – 1 之间对应的值。
  • BigInt.parseInt(string[, radix]):近似于 Number.parseInt(),将一个字符串转换成指定进制的 BigInt。
max 是 64 位带符号的 BigInt 所能示意的最大值
const max = 2n ** (64n - 1n) - 1n;

BigInt.asIntN(64, max)
// 9223372036854775807n
BigInt.asIntN(64, max + 1n)
// -9223372036854775808n
BigInt.asUintN(64, max + 1n)
// 9223372036854775808n

转换规则

能够应用 Boolean(),Number(),String(),(!)取反进行转换

Boolean(0n) // false
Boolean(1n) // true
Number(1n)  // 1
String(1n)  // "1"
!0n //true
!1n // false

数字运算

简直所有的数值运算符都能够用在 BigInt,然而有两个例外

  • 不带符号的右移位运算符 >>>
  • 一元的求正运算符 +

BigInt 不能与一般数值进行混合运算

1n + 1.3 // 报错

如果一个规范库函数的参数预期是 Number 类型,然而失去的是一个 BigInt,就会报错

// 谬误的写法
Math.sqrt(4n) // 报错

// 正确的写法
Math.sqrt(Number(4n)) // 2

其余运算

0n 会转为 false,其余值转为 true
BigInt 与字符串混合运算时,会先转为字符串,再进行运算。

退出移动版