ES6標準學習: 3、數值的擴展
數值的擴展
註:以下內容中: 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、數值的擴展