数值的扩展
注:以下内容中: 0 表示数字零, o 为英文字母。
一、二进制和八进制数值表示法
es6提供了二进制和八进制的数值表示法,分别用前缀0b(或者0B)和0o(或者0O)表示。
1 0b111110111 === 503 // true 2 0o767 === 503 // true
从es5开始,在严格模式中,八进制的数值就不允许使用0前缀表示,es6明确表示,要使用0o表示
1 // 非严格模式 2 (function () { 3 console.log(0o11 === 011) 4 })() // true 5 6 // 严格模式 7 (function () { 8 ‘use strict‘ 9 console.log(0o11 === 011) 10 })() // Uncaught SyntaxError: Octal literals are not allowed in strict mode.
将0b和0o前缀的字符串数值转为十进制数值,需要使用Number方法。
1 Number(‘0b111‘) // 7 2 Number(‘0o10‘) // 8
二、Number.isFinite(), Number.isNaN()
es6扩展了Number对象,新增加了两个方法:Number.isFinite()与Numeber.isNaN(),分别用来检查Infinite 与 NaN这两个特殊值
Number.isFinite()用来检测一个数值是否非无穷
1 Number.isFinite(NaN) // false 2 Number.isFinite(Infinite) // true 3 Number.isFinite(-Infinite) // true
Numeber.isNaN()用来检测一个值是否为NaN
1 Numeber.isNaN(NaN) // true 2 Numeber.isNaN(9/NaN) // true 3 Numeber.isNaN(‘true‘/0) // true 4 Numeber.isNaN(‘true‘/‘true‘) // true
三、Number.parseInt(), Number.parseFloat()
es6只是将这个两个全局方法移植到了Number对象上,方法的行为让然保持不变。
这么做的目的是为了减少全局性的方法的数量,从而使语言逐步趋向模块化。
四、Number.isInteger()
该方法用来判断一个值是否为整数
注:在JS的内部,整数和浮点数是同样的存储方式,所以3和3.0被视为同一个值
1 Number.isInteger(25) // true 2 Number.isInteger(25.0) // true
五、Number.EPSILON
es6在Number上新增加了一个极小的常量: EPSILON
1 Number.EPSILON 2 // 2.220446049250313e-16
为什么需要引入这个常量?在考虑这个问题之前,我们先来看一下浮点数的运算。
我们知道,浮点数的运算是不准确的:
1 0.1 + 0.2 // 0.30000000000000004
至于为什么会这样,可以自行查找浮点数的存储和运算相关资料。
那么,能不能有一个标准,如果我们的运算误差在这个标准之内,我们就可以认为得到了正确的值呢?这就是EPSILON的作用。
既然这个常量可以作为一个误差标准,我们就可以写出下面的函数
1 // 为浮点数运算增加一个误差检查函数 2 function errorCheck (left, right) { 3 return Math.abs(left - right) < Number.EPSILON 4 }
六、安全整数
js能够准确表示的整数范围在-2^{53} 与 2^{53}之间(不含两个端点),
以下是控制台的输出:
Math.pow(2, 53) ///9007199254740992 9007199254740992 //9007199254740992 9007199254740993 //9007199254740992 9007199254740993 === 9007199254740992 //true
es6引入了Number.MAX_SAFEINTEGER和Number.MIN_SAFE_INTEGER两个常量,用来表示这个范围的上下限。
1 Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 2 // true
1 Number.MIN_SAFE_INTEGER === -Math.pow(2, 53) + 1 2 // true
那么,如何确定一个数在这两个常量所处的范围之间呢?
Number.isSafeInteger()就是用来判断一个整数是否在这个范围之内。
注:当验证一个运算结果是否子啊安全范围之内时。不要仅仅只验证运算结果,参与运算的每个值也同样需要验证。
1 Number.isSafeInteger(9007199254740993) 2 //false 3 4 Number.isSafeInteger(990) 5 //true 6 7 Number.isSafeInteger(9007199254740993 - 990) 8 //true 9 10 9007199254740993 - 990 11 //9007199254740002
实际上,9007199254740993 - 990 = 9007199254740003 而不是 9007199254740002,因为 9007199254740993 不是一个安全整数,之所以isSafeInteger会返回计算结果安全,是因为9007199254740993 在存储时,就已经按照9007199254740992存储了,而不是9007199254740993。
所以,如果只验证运算结果是否安全,是不够的。以下是一个检测运算数和结果的函数:
1 function check (left, right, result) { 2 if (Number.isSafeInteger(left) && 3 Number.isSafeInteger(right) && 4 Number.isSafeInteger(result)) { 5 return result 6 } else { 7 thro new RangeErroe(‘error!‘) 8 }
七、Math对象的扩展
es6在Math对象上新增了许多与数学相关的新方法,这些方法都是静态方法。
1、Math.trunc() 用于去除一个数的小数部分,返回整数部分
(对于非数值,函数内部会先将其转化为数值)
(对于空值和无法截取整数的值,返回NaN)
1 Math.trunc(‘1123.111‘) 2 //1123 3 4 Math.trunc(‘foo‘) 5 //NaN
2、Math.sign() 用于判断一个数到底是正数、负数还是零。
该函数可能有以下几种返回值:
参数为正数,返回 +1
参数为负数,返回 -1
参数为0, 返回 0
参数为 -0, 返回 -0
其他值,返回NaN
3、Math.cbrt() 用于计算一个数的立方根
(对于非数值,函数内部也是先将其转化为数值)
4、Math.clz32() 该方法返回一个数的32位无符号正数形式有多少个前导0
1 Math.clz32(1000) //22
左移运算符(<<)与该函数直接相关。
对于小数,该方法只考虑整数部分
5、Math.imul() 该方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数
之所以要有这个方法,是因为对于那些很大的数相乘,由于js精度的限制,运算结果低位数值往往都是不准确的:
1 (0x7fffffff * 0x7fffffff) | 0 // 0
结果很明显是不对的,因为这个两个运算数值的最低位都是1,所以计算结果的最低位也应该是1,之所以错误是因为他们的乘积超过了js的精度范围,而该方法可以正确的返回1
1 Math.imul(0x7fffffff, 0x7fffffff) // 1
6、Math.fround() 该方法返回一个数的单精度浮点数形式
对于整数来说,这个方法返回的记结果不会有什么不同,主要区别在于那些无法用64个位二进制位精确表示的小数。这时,这个函数会返回最接近这个小数的值。
7、Math.hypot() 该方法返回所有参数的平方和的平方根
如果参数不是数值,该函数首先会将其转为数值,只要有一个参数无法转换,返回NaN
8、对数方法
es6新增了4个对数有关的方法
>>>>>Math.expm1() 返回e^x -1 ,即Math.exp(x) - 1
>>>>>Math.log1p() 返回ln(1 + x),即Math.log(1 + x),如果x小于-1,返回NaN
>>>>>Math.log10() 返回以10为底的x的对数,如果x小于 0,返回NaN
>>>>>Math.log2()返回以2为底的x的对数,如果x小于0,返回NaN
9、三角函数方法
>>>>>Math.sinh(x) 返回x的双曲正弦
>>>>>Math.cosh(x)返回x的双曲余弦
>>>>>Math.tanh(x)返回x的双曲正切
>>>>>Math.asinh(x) 返回x的反双曲正弦
>>>>>Math.acosh(x) 返回x的反双曲余弦
>>>>> Math.atanh(x) 返回x的反双曲正切
10、指数运算符
es7新增加了一个指数运算符( ** )
1 2 ** 2 // 4
// 可以与 =号 结合 let a = 2 a ** = 2 // 等同于 a = a * a
以上就是es6中关于数值的扩展的部分。
参考书籍<<ES6标准入门——阮一峰>>