ES6+ 數值擴展
1. 前言
ES6 對數值進行了大的改版,在向下兼容的同時,把所有的數值方法由全局移植到了 Number 對象下,在數組和字符串中也做了類似的操作,這樣的主要目的是精簡全局方法,更加明確的表達方法的含義。另外,ES6 還增加了二進制和八進制的表示方法,并增加了很多數值處理的方法,本節就來看看 ES6 對數值的擴展。
2. Number 對象
JavaScript 的 Number
對象是經過封裝的,能讓你處理數字值的對象, Number
對象由 Number()
構造器創建。
2.1 類型轉換
在非構造器上下文中,也就是沒有 new
操作符時,Number
可以類型轉換的函數使用。 接收一個參數,并將這個參數轉換為數字,如果參數無法被轉換為數字,則返回 NaN
。
Number('10') // 10
Number('imooc') // NaN
Number('') // 0
Number() // 0
Number(undefined) // NaN
上面的代碼中,在沒有字符串或者是空字符串的時候,會得到數字 0,還有參數是 null
時得到的結果也是 0。但是,當參數為 undefined
時則會得到 NaN
。
2.2 移植全局方法
在 ES5 中,如 parseFloat
、parseInt
等都是全局方法,在 ES6 中把處理數值的一些方法都移植到了 Number 對象上了。
parseInt('123'); // 123
Number.parseInt('123'); // 123
上面的代碼可以看到,Number 對象下也有 parseInt
的方法,并且所有的數值方法在 Number 上也是一一對應的,功能基本相同,有些方法還做了擴展。在后面的小節中我們會對 Number 上的方法和全局的方法進行對比,看它們有什么不同,ES6 又解決了什么問題。
3. 二進制和八進制表示法
ES6 提供了二進制和八進制數值表示的新寫法,分別用前綴 0b
(或 0B
)和 0o
(或 0O
)表示。對應的十六進制我們知道用 0x
作為前綴來表示的。下面我們來看看二進制和八進制是怎么表示的。
// es6 2進制 0B 開頭
console.log('B',0B111110111); // 503
console.log('B',0b111110111); // 相同,0B 和 0b 都可以
// es6 8進制 0o 開頭
console.log(0o767); // 503
console.log(0O767); // 相同,0o 和 0O 都可以
上面的代碼分別使用了二進制和八進制對數字 503 進行了表示,那下面我們來驗證一下:
0b111110111 === 503 // true
0o767 === 503 // true
上面的代碼中使用了全等的方式進行判斷,很明顯,ES6 是支持這種方式的表示的。
從 ES5 開始,在嚴格模式之中,八進制就不再允許使用前綴 0
表示,ES6 進一步明確,要使用前綴 0o
表示。
// 非嚴格模式
(function(){
console.log(0o11 === 011); // true
})()
// 嚴格模式
(function(){
'use strict';
console.log(0o11 === 011);
})()
// Uncaught SyntaxError: Octal literals are not allowed in strict mode.
將 0b
和 0o
前綴的字符串數值轉為十進制,可以把 Number
對象直接作為方法使用。
Number('0b111') // 7
Number('0o10') // 8
4. Number 的屬性介紹
ES6 對 Number 的屬性進行了豐富,能夠適用更多的場景。
4.1 Number.EPSILON
ES6 在 Number 對象上面,新增一個極小的常量 Number.EPSILON
。它表示 1 與大于 1 的最小浮點數之間的差。它是一個差值,屬于正數。
你不必創建一個 Number 對象來訪問這個靜態屬性(可以直接使用 Number.EPSILON)。
console.log(Number.EPSILON) // 2.220446049250313e-16
EPSILON 屬性的值接近于 2.2204460492503130808472633361816E-16,或者 2 的 -52 次方。
對于 64 位浮點數來說,大于 1 的最小浮點數相當于二進制的 1.00…001,小數點后面有連續 51 個零。這個值減去 1 之后,就等于 2 的 -52 次方。
0.1 + 0.2
// 0.30000000000000004
0.1 + 0.2 - 0.3
// 5.551115123125783e-17
5.551115123125783e-17.toFixed(20)
// '0.00000000000000005551'
上面代碼解釋了,為什么比較0.1 + 0.2與0.3得到的結果是false。
0.1 + 0.2 === 0.3 // false
Number.EPSILON 實際上是 JavaScript 能夠表示的最小精度。誤差如果小于這個值,就可以認為已經沒有意義了,即不存在誤差了。
引入一個這么小的量的目的,在于為浮點數計算,設置一個誤差范圍。我們知道浮點數計算是不精確的。
5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2)
// true
4.2 Number.MAX_SAFE_INTEGER
Number.MAX_SAFE_INTEGER
常量表示在 JavaScript 中最大的安全整數(maxinum safe integer)(2e53 - 1
)。
console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
MAX_SAFE_INTEGER
是一個值為 9007199254740991 的常量。因為 Javascript 的數字存儲使用了 IEEE-754 中規定的雙精度浮點數數據類型,而這一數據類型能夠安全存儲 -(2e53 - 1)
到 2e53 - 1
之間的數值(包含邊界值)。
由于 MAX_SAFE_INTEGER
是 Number 的一個靜態屬性,所以你不用自己動手為 Number 對象創建 Number.MAX_SAFE_INTEGER
這一屬性,就可以直接使用它。
4.3 Number.MIN_SAFE_INTEGER
Number.MIN_SAFE_INTEGER
代表在 JavaScript 中最小的安全的 integer 型數字 (-(253 - 1)
)。
console.log(Number.MIN_SAFE_INTEGER) // -9007199254740991
MIN_SAFE_INTEGER
的值是 -9007199254740991
. 形成這個數字的原因是 JavaScript 在 IEEE-754 中規定的。在這個規定中能安全地表示數字的范圍在 -(2e53 - 1)
到 2e53 - 1之間
。
由于 MIN_SAFE_INTEGER
是 Number 的一個靜態屬性,你可以直接使用 Number.MIN_SAFE_INTEGER
, 而不是自己去創建一個 Number 的屬性。
5. 小結
本節主要講解了 ES6 對數值的擴展主要總結一下幾點:
- 增加了二進制和八進制表示法;
- 直接使用 Number 進行類型轉換;
- 移植了原有的方法到 Number 對象上;
- 對新增的 Number 對象上的屬性做了簡單的解釋。
ES6 的 Number 對象還提供了很多方法,下面的小節會講到,還有 ES6 對數字的處理在 Math 小節做詳細的講解。