1. 程式人生 > >ES6標準學習: 3、數值的擴展

ES6標準學習: 3、數值的擴展

平方和 全局 oat 數值 限制 相關 模式 安全 不同

數值的擴展

註:以下內容中: 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標準入門——阮一峰>>

ES6標準學習: 3、數值的擴展