ES6第七章数值的扩展

数值的扩展

  • 二进制和八进制表示法

二进制前缀0b(或0B)八进制和0o(或0O)表示。

	0b111110111 === 503 // true
	0o767 === 503 // true
如果要将0b和0o前缀的字符串数值转为十进制,要使用Number方法。
	Number('0b111')  // 7
	Number('0o10')  // 8
  • Number.isFinite(), Number.isNaN()

    ES6 在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法。
    Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity

    Number.isFinite(15); // true
    Number.isFinite(0.8); // true
    Number.isFinite(NaN); // false
    Number.isFinite(Infinity); // false
    Number.isFinite(-Infinity); // false
    

    Number.isNaN()用来检查一个值是否为NaN

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

    Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false

  • Number.parseInt(), Number.parseFloat()

    ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。

    // ES5的写法
    parseInt('12.34') // 12
    parseFloat('123.45#') // 123.45
    
    // ES6的写法
    Number.parseInt('12.34') // 12
    Number.parseFloat('123.45#') // 123.45
    
  • Number.isInteger()
    Number.isInteger()用来判断一个数值是否为整数。
    但是由于整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值。还有就是精度问题,由于 JavaScript 采用 IEEE 754 标准,数值存储为64位双精度格式,数值精度最多可以达到 53 个二进制位(1 个隐藏位与 52 个有效位)。如果数值的精度超过这个限度,第54位及后面的位就会被丢弃,这种情况下,Number.isInteger可能会误判。

    Number.isInteger(3.0000000000000002) // true
    

    如果一个数值的绝对值小于Number.MIN_VALUE(5E-324),即小于 JavaScript 能够分辨的最小值,会被自动转为 0。这时,Number.isInteger也会误判。
    总之如果对数据精度的要求较高,不建议使用Number.isInteger()判断一个数值是否为整数。

  • Number.EPSILON
    Number.EPSILON实际上是 JavaScript 能够表示的最小精度。误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了。
    引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。小于这个范围就可以忽略误差了。

    	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) // true
    
  • 安全整数和 Number.isSafeInteger()

    JavaScript 能够准确表示的整数范围在-2^53到 2^53之间(不含两个端点),超过这个范围,无法精确表示这个值。
    ES6 引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。

    Number.isSafeInteger()则是用来判断一个整数是否落在JavaScript 能够精确表示的极限范围之内。

    Number.isSafeInteger = function (n) {
    	  return (typeof n === 'number' &&
    	  		Math.round(n) === n &&
    	   		Number.MIN_SAFE_INTEGER <= n &&
    	   		n <= Number.MAX_SAFE_INTEGER
    	   	);
    	}
    
Math 对象的扩展
  • Math.trunc() 用于去除一个数的小数部分,返回整数部分
    	Math.trunc(4.9) // 4
    	Math.trunc(-4.1) // -4
    	Math.trunc(-4.9) // -4
    
    • 对于非数值,Math.trunc内部使用Number方法将其先转为数值。
    • 对于空值和无法截取整数的值,返回NaN。
  • Math.sign() 用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
    • 参数为正数,返回+1;
      参数为负数,返回-1;
      参数为 0,返回0;
      参数为-0,返回-0;
      其他值,返回NaN。
  • Math.cbrt()用于计算一个数的立方根。
    Math.cbrt(-1) // -1
    Math.cbrt(0)  // 0
    Math.cbrt(1)  // 1
    Math.cbrt(2)  // 1.2599210498948732
    
    对于非数值,Math.cbrt()方法内部也是先使用Number()方法将其转为数值。
  • Math.clz32() 方法将参数转为 32 位无符号整数的形式,然后返回这个 32 位值里面有多少个前导 0
    Math.clz32(0) // 32
    Math.clz32(1) // 31
    Math.clz32(1000) // 22
    
    也就在左移和右移有用到就可以看到最多可以移位多少。
  • Math.imul() 返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。
    Math.imul(2, 4)   // 8
    Math.imul(-1, 8)  // -8
    
    看起来Math.imul(2, 4) 和直接2*4结果是一样的但是,实际上不一样因为前面说过的精度问题,Math.imul(2, 4)实际上等于(a * b)|0。所以对于那些很大的数的乘法,低位数值往往都是不精确的,Math.imul方法可以返回正确的低位数值。
  • Math.fround() 返回一个数的32位单精度浮点数形式。

    Math.fround方法的主要作用,是将64位双精度浮点数转为32位单精度浮点数。(32位精度,1位符号,八位阶码,所以精度是23位,但是有一位是固定的所以是24位精度)如果小数的精度超过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
    
  • 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
    

对数方法

  • Math.expm1() : Math.expm1(x)返回 e^x - 1,即Math.exp(x) - 1。
    	Math.expm1(-1) // -0.6321205588285577
    	Math.expm1(0)  // 0
    	Math.expm1(1)  // 1.718281828459045
    
  • Math.log1p() : Math.log1p(x)方法返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN。
    	Math.log1p(1)  // 0.6931471805599453
    	Math.log1p(0)  // 0
    	Math.log1p(-1) // -Infinity
    	Math.log1p(-2) // NaN
    
  • Math.log10(): Math.log10(x)返回以 10 为底的x的对数。如果x小于 0,则返回 NaN。
    	Math.log10(2)      // 0.3010299956639812
    	Math.log10(1)      // 0
    	Math.log10(0)      // -Infinity
    	Math.log10(-2)     // NaN
    	Math.log10(100000) // 5
    
  • Math.log2(): Math.log2(x)返回以 2 为底的x的对数。如果x小于 0,则返回 NaN。
    	Math.log2(3)       // 1.584962500721156
    	Math.log2(1)       // 0
    	Math.log2(0)       // -Infinity
    	Math.log2(-2)      // NaN
    	Math.log2(1024)    // 10
    	Math.log2(1 << 29) // 29
    
  • 双曲函数方法

    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)

  • 指数运算符
    ES2016 新增了一个指数运算符()如(2 ** 2 )==(2^2)
    指数运算符可以与等号结合,形成一个新的赋值运算符(
    =)
    let b = 4;
    b **= 3;
    // 等同于 b = b * b * b;
    
  • BigInt 数据类型
    ES2020 引入了一种新的数据类型 BigInt(大整数),来解决于或等于2的1024次方的数值,JavaScript 无法表示这个问题。这是 ECMAScript 的第八种数据类型。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
    为了与 Number 类型区别,BigInt 类型的数据必须添加后缀n。
    1234n // BigI表示
    BigInt 同样可以使用各种进制表示,都要加上后缀n。
    0b1101n // 二进制
    0o777n // 八进制
    0xFFn // 十六进制
    

    BigInt 与普通整数是两种值,它们之间并不相等。
    BigInt 可以使用负号(-),但是不能使用正号(+),因为会与 asm.js 冲突
  • BigInt 对象

    JavaScript 原生提供BigInt对象,可以用作构造函数生成 BigInt 类型的数值。转换规则基本与Number()一致,将其他类型的值转为 BigInt。

    BigInt(123) // 123n
    BigInt('123') // 123n
    
    BigInt()构造函数必须有参数,而且参数必须可以正常转为数值,参数如果是小数,也会报错。

    BigInt 对象继承了 Object 对象的两个实例方法。
    BigInt.prototype.toString()
    BigInt.prototype.valueOf()
    它还继承了 Number 对象的一个实例方法。
    BigInt.prototype.toLocaleString()
    静态方法
    1. BigInt.asUintN(width, BigInt): 给定的 BigInt 转为 0 到 2width - 1 之间对应的值。
    2. BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2width - 1 到 2width - 1 - 1 之间对应的值。
    3. BigInt.parseInt(string[, radix]):近似于Number.parseInt(),将一个字符串转换成指定进制的 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()这三个方法,将 BigInt 可以转为布尔值、数值和字符串类型。
    	Boolean(0n) // false
    	Boolean(1n) // true
    	Number(1n)  // 1
    	String(1n)  // "1"
    
    取反运算符(!)也可以将 BigInt 转为布尔值!0n !1n
  • 数学运算
    • BigInt 类型的+、-、*和**这四个二元运算符,与 Number 类型的行为一致。除法运算/会舍去小数部分,返回一个整数
    • BigInt 不能与普通数值进行混合运算。
      无论返回的是 BigInt 或 其他类型,都会导致丢失精度信息
    • 不带符号的右移位运算符>>>
      因为>>>运算符是不带符号的,但是 BigInt 总是带有符号的,导致该运算无意义,完全等同于右移运算符>>。
    • 一元的求正运算符+
      一元运算符+在 asm.js 里面总是返回 Number 类型,为了不破坏 asm.js 就规定+1n会报错
  • 其他运算
    • BigInt 对应的布尔值,与 Number 类型一致,即0n会转为false,其他值转为true。
    • BigInt 与字符串混合运算时,会先转为字符串,再进行运算
      '' + 123n // "123"
    • 比较运算符(比如>)和相等运算符(==)允许 BigInt 与其他类型的值混合计算
    	0n < 1 // true
    	0n < true // true
    	0n == 0 // true
    	0n == false // true
    	0n === 0 // false
    

你可能感兴趣的:(ES6第七章数值的扩展)