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