ES6 学习(6) ---数值

数值

  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

-----不生产代码,只是代码的搬运工

原文地址:https://www.cnblogs.com/newttt/p/12483380.html