# ES6 Math 对象的扩展

73 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

ES6 Math 对象的扩展

定义和使用

ES6 在 Math 对象上新增了 17 个与数学相关的方法。所有这些方法都是静态方法,只能在 Math 对象上调用。

Math.trunc()

Math.trunc 方法用于去除一个数的小数部分,返回整数部分。

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 内部使用 Number 方法将其先转为数值。


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


对于空值和无法截取整数的值,返回 NaNMath.trunc(NaN);      // NaN
Math.trunc('foo');    // NaN
Math.trunc();         // NaN
Math.trunc(undefined) // NaN


对于没有部署这个方法的环境,可以用下面的代码模拟。


Math.trunc = Math.trunc || function(x) {
  return x < 0 ? Math.ceil(x) : Math.floor(x);
};

Math.sign()

Math.sign 方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

它会返回五种值。

-   参数为正数,返回  +1;
-   参数为负数,返回 -1;
-   参数为 0,返回 0;
-   参数为 -0,返回 -0;
-   其他值,返回 NaNMath.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


对于没有部署这个方法的环境,可以用下面的代码模拟。

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 方法用于计算一个数的立方根。

Math.cbrt(-1) // -1
Math.cbrt(0)  // 0
Math.cbrt(1)  // 1
Math.cbrt(2)  // 1.2599210498948734

对于非数值,Math.cbrt 方法内部也是先使用 Number 方法将其转为数值。


Math.cbrt('8') // 2
Math.cbrt('hello') // NaN


对于没有部署这个方法的环境,可以用下面的代码模拟。


Math.cbrt = Math.cbrt || function(x) {
  var y = Math.pow(Math.abs(x), 1/3);
  return x < 0 ? -y : y;
};

Math.clz32()

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


上面代码中,0 的二进制形式全为 0,所以有 32 个前导 01 的二进制形式是0b1,只占 1 位,所以 32 位之中有 31 个前导 01000 的二进制形式是 0b1111101000,一共有 10 位,所以 32 位之中有 22 个前导 0。

clz32 这个函数名就来自”count leading zero bits in 32-bit binary representation of a number“(计算一个数的 32 位二进制形式的前导 0 的个数)的缩写。

左移运算符(<<)与 Math.clz32 方法直接相关。


Math.clz32(0) // 32
Math.clz32(1) // 31
Math.clz32(1 << 1) // 30
Math.clz32(1 << 2) // 29
Math.clz32(1 << 29) // 2


对于小数,Math.clz32 方法只考虑整数部分。

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