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()
的參數類型如果不是數值,一律返回false
;Number.isNan()
的參數如果不是NaN
,一律返回true
。
2.1 Number.isFinite(),Number.isNaN()與全局方法isFinite(),isNaN()的區別
全局方法isFinite()
和isNaN()
會先調用Number()
方法將非數值類型的參數轉換爲數據類型的值,然後再進行判斷,而Number.isFinite()
與Number.isNaN()
兩個方法只對數值有效。Number.isFinite()
的參數如果不是數值類型,一律返回false
。Number.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
上面代碼中,5
和5.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 能夠準確表示的整數範圍在-253
和253
之間(開區間),超過這個範圍,無法精確表示這個值。
ES6 引入了Number.MAX_SAFE_INTEGER
和Number.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
個二進制位,而且大於或等於2
的1024
次方的數值(小於或等於-2
的1023
次方的數值),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 入門
如有問題,請及時指出!
歡迎溝通交流,郵箱:[email protected]。