ECMAScript 6之数值的扩展

ECMAScript 6之数值的扩展

1. 二进制和八进制的表示

ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。

// 数值转为二进制字符
(369).toString(2); // "101110001"
// 数值转为八进制字符
369..toString(8); // "561"

// 二进制用0b或oB表示
0b101110001 === 369; // true
0B101110001 === 369; // true

// 八进制用0o或0O表示
0o561 === 369; // true
0O561 === 369; // true

上面代码中,数值369没有直接调用toString()方法,如果不加括号直接调用toString(),这个点会被 JavaScript 引擎解释成小数点,从而报错。有以下方法可以避免这个问题。

  • 数值加上括号(()
  • 在数值后面加两个点,JavaScript 会把第一个点理解成小数点,把第二个点理解成调用对象属性,从而得到正确结果
  • 通过方括号运算符([])调用
// 数值加()调用
(234).toString(2); // "11101010"
// 数值加.调用
234..toString(2); // "11101010"
// 通过[]调用
234['toString'](2); // "11101010"

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

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

// Number.isFinite()检查一个数是否是有限的
Number.isFinite(15); // true
Number.isFinite(0.8); // true

// 参数类型不是数值,一律返回false
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('jidi'); // false
Number.isFinite('1'); // false
Number.isFinite(true); // false


// Number.isNaN()检查一个数是否为NaN
Number.isNaN(NaN) // true
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true

// 参数类型不是NaN,一律返回false
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false

注意:·Number.isFinite()的参数类型如果不是数值,一律返回falseNumber.isNan()的参数如果不是NaN,一律返回true

2.1 Number.isFinite(),Number.isNaN()与全局方法isFinite(),isNaN()的区别

全局方法isFinite()isNaN()会先调用Number()方法将非数值类型的参数转换为数据类型的值,然后再进行判断,而Number.isFinite()Number.isNaN()两个方法只对数值有效。Number.isFinite()的参数如果不是数值类型,一律返回falseNumber.isNaN()的参数非NaN一律返回true

// isFinite()会先调用Number方法进行数据类型转换,然后进行判断
isFinite(25); // true
isFinite("25"); // true

// Number.isFinite()只对数值有效
Number.isFinite(25); // true
Number.isFinite("25"); // false

// isNaN()会先调用Number方法进行数据类型转换,然后进行判断
isNaN(NaN) // true
isNaN("NaN") // true

// Number.isNaN()只对数值有效
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
Number.isNaN(1) // false

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

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

// ES5写法
parseInt('123'); // 123
parseInt('   81'); // 81
parseInt(1.23); // 1
parseInt('8a'); // 8
parseInt('12**'); // 12
parseInt('12.34'); // 12
parseInt('15e2'); // 15
parseInt('15px'); // 15
parseInt('abc'); // NaN
parseInt('.3'); // NaN
parseInt(''); // NaN
parseInt('+'); // NaN
parseInt('1000', 2); // 8
parseInt('1000', 6); // 216
parseInt('1000', 8); // 512

// ES6写法
Number.parseInt('123'); // 123
Number.parseInt('   81'); // 81
Number.parseInt(1.23); // 1
Number.parseInt('8a'); // 8
Number.parseInt('12**'); // 12
Number.parseInt('12.34'); // 12
Number.parseInt('15e2'); // 15
Number.parseInt('15px'); // 15
Number.parseInt('abc'); // NaN
Number.parseInt('.3'); // NaN
Number.parseInt(''); // NaN
Number.parseInt('+'); // NaN
Number.parseInt('1000', 2); // 8
Number.parseInt('1000', 6); // 216
Number.parseInt('1000', 8); // 512

4. Number.isInteger()

Number.isInteger()用来判断一个数值是否为整数。

Number.isInteger(5); // true
Number.isInteger(5.0); // true
Number.isInteger(5.6); // false

上面代码中,55.0结果一样,因为javaScript内部,整数和浮点数用的同一种存储方法(参考JavaScript教程)。

根据国际标准 IEEE 754,JavaScript 提供的有效数字最长为53个二进制位。当数值的精度超过这个标准,Number.isInteger()会失真。

// 超过精度范围,判断失真
Number.isInteger(1.000000000000000000000000000000000000002); // true

5. Number.EPSILON

ES6 新增一个极小的常量Number.EPSILON,它表示 1 与大于1的最小浮点数之间的差。由于数字在javaScript内部使用64位浮点数存储,所以Number.EPSILON相当于2-52次方。

Number.EPSILON === Math.pow(2, -52); // true
Number.EPSILON; // 2.220446049250313e-16

由于浮点数的计算是不精确的,Number.EPSILON的实质是一个可以接受的最小误差范围。

// 浮点数的计算是不精确的
0.1 + 0.7; // 0.7999999999999999

// 在最小误差范围内,可以认为两个数相等
2 + Number.EPSILON === 2;

6. 安全整数和 Number.isSafeInteger()

JavaScript 能够准确表示的整数范围在-253253之间(开区间),超过这个范围,无法精确表示这个值。
ES6 引入了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内.。

Math.pow(2, 53) - 1; // 9007199254740991
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1; // true
Number.MAX_SAFE_INTEGER === 9007199254740991; // true

Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER; // true
Number.MIN_SAFE_INTEGER === -9007199254740991; // true

// 判断一个数是否在-9007199254740991~9007199254740991之间
Number.isSafeInteger('jidi'); // 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

注意:使用Number.isSafeInteger()函数进行验证时,不要只验证运算结果,而要同时验证参与运算的每个值

7. 指数运算符

ES2016 新增了一个指数运算符(**)。**是右结合的,多个指数运算可以连用。

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

// 多个指数运算符连用
2 ** 3 ** 2; // 512

8. BigInt 数据类型

由于JavaScript 所有数字都用64 位浮点数进行存储,数值的精度只能到 53 个二进制位,而且大于或等于21024次方的数值(小于或等于-21023次方的数值),JavaScript 无法表示,会返回Infinity-Infinity)。

// 超过 53 个二进制位的数值,无法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1; // true

// 超过 2 的 1024 次方的数值,无法表示
Math.pow(2, 1025); // Infinity

ES2020 引入了一种新的数据类型 BigInt,来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。BigInt 类型的数据必须添加后缀n

// Bigint数据后面加后缀n
const a = 21721416122353n;
const b = 153463491231309n;

// BigInt精度可以保证
a*b; // 3333444352624333556168350077n

Bigint类型的数据与普通数值是两种值,并不相等。

const c1 = 12n;
const c2 = 12;

typeof c1; // "bigint"
typeof c2; // "number"

// 两者不相等
c1 === c2; // false

8.1 BigInt 对象

JavaScript 原生提供BigInt对象,可以用作构造函数生成 BigInt 类型的数值。BigInt()构造函数必须有参数,而且参数必须可以正常转为数值。

// 用法参照Number()
BigInt(123) // 123n
BigInt('123') // 123n
BigInt(false) // 0n
BigInt(true) // 1n

// Bigint()必须有参数,且参数必须能转为数值
new BigInt(); // Uncaught TypeError: BigInt is not a constructor at new BigInt 
BigInt(undefined); // Uncaught TypeError: Cannot convert undefined to a BigInt
BigInt(null); // Uncaught TypeError: Cannot convert null to a BigInt at BigInt 
BigInt(NaN); // Uncaught RangeError: The number NaN cannot be converted to a BigInt because it is not an integer
BigInt(Infinity); // Uncaught RangeError: The number Infinity cannot be converted to a BigInt because it is not an integer at BigInt

BigInt()构造函数参数不能为小数。

BigInt(1.1); // Uncaught RangeError: The number 1.1 cannot be converted to a BigInt because it is not an integer at BigInt 

BigInt 类型的+-***这四个二元运算符,与 Number 类型的行为一致。除法运算/会舍去小数部分,返回一个整数。

12n + 12n; // 24n
2n * 2n; // 4n
12n - 2n; // 10n
2n ** 3n; // 8n

// 除法会舍去小数部分,返回整数
10n / 6n; // 1n

BigInt 不能与普通数值进行混合运算。

1n + 32; // Uncaught TypeError: Cannot mix BigInt and other types

有两个数值运算符不能用在Bigint数据类型的值上。

  • 无符号右移>>>
  • 一元求正+

>>>是无符号右移,而Bigint数据类型的总是带符号的,所以该运算无意义;而一元+运算符结果是返回Number的,会报错。

+ 12n; // Uncaught TypeError: Cannot convert a BigInt value to a number

跟一元求正运算符一样,如果一个标准库函数的参数预期是Number 类型,但是得到的是一个 BigInt,就会报错。

Math.pow(2n, 2); // Uncaught TypeError: Cannot convert a BigInt value to a number  at Math.pow
Math.abs(4n); // Uncaught TypeError: Cannot convert a BigInt value to a number at Math.abs

9. 参考链接

本篇博文是我自己学习笔记,原文请参考:ECMAScript 6 入门
如有问题,请及时指出!
欢迎沟通交流,邮箱:jidi_jidi@163.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值