前言
本章介紹數(shù)值的擴(kuò)展。新增了很多方法,有些不常用的方法了解即可。
本章原文鏈接:數(shù)值的擴(kuò)展
進(jìn)制表示法
ES6 提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴0b
(或0B
)和0o
(或0O
)表示。
八進(jìn)制就不再允許使用前綴0
表示。0b
和0o
前綴的字符串?dāng)?shù)值轉(zhuǎn)為十進(jìn)制,要使用Number
方法。
console.log(Number(0b10)); // 二進(jìn)制 2console.log(Number(0o10)); // 八進(jìn)制 8
數(shù)值分隔符
ES2021,允許 JavaScript 的數(shù)值使用下劃線(_)作為分隔符。
數(shù)值分隔符主要為了書寫數(shù)值時(shí)增加數(shù)值的可讀性,不是為了處理外部輸入的數(shù)據(jù),對(duì)于 JavaScript 內(nèi)部數(shù)值的存儲(chǔ)和輸出,并沒有影響。
注意:
- 不能放在數(shù)值的最前面(
leading
)或最后面(trailing
)。 - 不能兩個(gè)或兩個(gè)以上的分隔符連在一起。
- 小數(shù)點(diǎn)的前后不能有分隔符。
- 科學(xué)計(jì)數(shù)法里面,表示指數(shù)的
e
或E
前后不能有分隔符。 - 分隔符不能緊緊跟著進(jìn)制的前綴
- 字符串轉(zhuǎn)數(shù)值的一些操作方法不支持?jǐn)?shù)值分隔符
其它進(jìn)制也能使用數(shù)值分隔符
const sample10 = 1000_1000_1000;const sample2 = 0b1000_1000;const sample8 = 0o1000_1000;console.log(sample10); // 十進(jìn)制 100010001000console.log(sample2); // 二進(jìn)制 136console.log(sample8); // 八進(jìn)制 2097664
注意:Number()、parseInt()、parseFloat()不支持?jǐn)?shù)字分隔符
數(shù)值的方法
Number.isFinite(), Number.isNaN()
ES6 在Number對(duì)象上,新提供了Number.isFinite()
和Number.isNaN()
兩個(gè)方法。
Number.isFinite()
用來檢查一個(gè)數(shù)值是否為有限的數(shù)字(finite
),即不是Infinity
。Number.isNaN()
用來檢查一個(gè)數(shù)值是否為NaN。
注意:
兩個(gè)新方法與之前全局方法isFinite
、isNaN
有什么不同呢?
- 而這兩個(gè)新方法只對(duì)數(shù)值有效,
- 傳統(tǒng)方法先調(diào)用
Number()
將非數(shù)值的值轉(zhuǎn)為數(shù)值,再進(jìn)行判斷,
isFinite(25) // trueisFinite("25") // trueNumber.isFinite(25) // trueNumber.isFinite("25") // falseNumber.isFinite(Infinity); // falseNumber.isFinite(-Infinity); // falseisNaN(NaN) // trueisNaN("NaN") // trueNumber.isNaN(NaN) // trueNumber.isNaN("NaN") // false
Number.parseInt(), Number.parseFloat()
ES6 將全局方法parseInt()
和parseFloat()
,移植到Number
對(duì)象上面,行為完全保持不變。主要是用于全局變量的模塊化
parseInt()
函數(shù)解析字符串并返回整數(shù)。parseFloat()
函數(shù)解析字符串并返回浮點(diǎn)數(shù)。
// ES5的全局方法const sampleInt = parseInt(11.11);const sampleFloat = parseFloat(1a2b3c);// ES6的Number方法const sampleInt1 = Number.parseInt(11.11);const sampleFloat1 = Number.parseFloat(1a2b3c);console.log(sampleInt, sampleFloat); // 11, 1console.log(sampleInt1, sampleFloat1); // 11, 1
Number.isInteger()
Number.isInteger()
方法用來判斷給定的參數(shù)是否為整數(shù)。
注意:
- 由于整數(shù)和浮點(diǎn)數(shù)采用的是同樣的儲(chǔ)存方法,所以 4 和 4.0 被視為同一個(gè)值。都為整數(shù)
- 參數(shù)需要為數(shù)值,參數(shù)不是數(shù)值,
Number.isInteger()
直接返回false
。 - 由于 JavaScript 數(shù)值精度最多可以達(dá)到 53 個(gè)二進(jìn)制位,如果數(shù)值的精度超過這個(gè)限度,第54位及后面的位就會(huì)被丟棄,會(huì)導(dǎo)致
Number.isInteger
可能會(huì)誤判。絕對(duì)值也是如此。
const sample1 = Number.isInteger(44);const sample2 = Number.isInteger(44.00); // 相當(dāng)于 44 const sample3 = Number.isInteger(44); // 非數(shù)值直接返回falseconst sample4 = Number.isInteger(44.0000000000000000987654321); // 誤判為trueconsole.log(sample1, sample2, sample3, sample4); // true, true, false, true
數(shù)值新增常量
Number.EPSILON
ES6 在Number
對(duì)象上面,新增一個(gè)極小的常量Number.EPSILON
。它表示 1 與大于 1 的最小浮點(diǎn)數(shù)之間的差。
對(duì)于 64 位浮點(diǎn)數(shù)來說,大于 1 的最小浮點(diǎn)數(shù)相當(dāng)于二進(jìn)制的1.00..001
(小數(shù)點(diǎn)后面有連續(xù) 51 個(gè)零),這個(gè)值減去 1 之后,就等于 2 的 -52 次方。Number.EPSILON
實(shí)際上是 JavaScript 能夠表示的最小精度。Number.EPSILON
實(shí)質(zhì)是一個(gè)可以接受的最小誤差范圍。
const sample = Number.EPSILON === Math.pow(2, -52);console.log(sample); // const sample1 = Number.EPSILON;console.log(sample1); // const sample2 = Number.EPSILON.toFixed(20);console.log(sample2); //
安全整數(shù)和 Number.isSafeInteger()
JavaScript 能夠準(zhǔn)確表示的整數(shù)范圍在-2^53到2^53之間(不含兩個(gè)端點(diǎn)),超過這個(gè)范圍,無法精確表示這個(gè)值。
ES6 引入了Number.MAX_SAFE_INTEGER
和Number.MIN_SAFE_INTEGER
這兩個(gè)常量,用來表示-2^53到2^53
上下限。
const sample = Number.MAX_SAFE_INTEGER === 9007199254740991;const sample1 = Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER;const sample2 = Number.MIN_SAFE_INTEGER === -9007199254740991;console.log(sample,sample1,sample2);
Number.isSafeInteger()
用來判斷一個(gè)整數(shù)是否落在這個(gè)范圍之內(nèi),對(duì)于非整數(shù),全部返回false
?
const sample = Number.isSafeInteger(44); // 整數(shù)const sample1 =Number.isSafeInteger(44.001); // 非整數(shù)const sample3 =Number.isSafeInteger(9007199254740990);const sample3 =Number.isSafeInteger(9007199254740992);console.log(sample,sample1,sample2,sample3); // true, false, true, false
Math 對(duì)象的擴(kuò)展
ES6 在 Math 對(duì)象上新增了 17 個(gè)與數(shù)學(xué)相關(guān)的方法。
所有這些方法都是靜態(tài)方法,只能在 Math 對(duì)象上調(diào)用。
- Math.trunc() - 取整。
- Math.sign() - 判斷數(shù)字是正數(shù)、負(fù)數(shù)、還是零。
- Math.cbrt() - 計(jì)算一個(gè)數(shù)的立方根
- Math.clz32() - 計(jì)算一個(gè)數(shù)的 32 位二進(jìn)制形式的前導(dǎo) 0 的個(gè)數(shù) 。
- Math.imul() - 計(jì)算兩個(gè)參數(shù)的類 C 32 位乘法的。
- Math.fround() - 返回一個(gè)數(shù)的32位單精度浮點(diǎn)數(shù)形式。
- Math.hypot() - 返回所有參數(shù)的平方和的平方根。
- Math.expm1() - 返回 ex - 1,x為參數(shù)
- Math.log1p() - 返回參數(shù) + 1 后的自然對(duì)數(shù)
- Math.log10() - 返回以 10 為底的參數(shù)對(duì)數(shù)
- Math.log2() - 返回以 2 為底的參數(shù)對(duì)數(shù)
- Math.sinh() - 函數(shù)返回一個(gè)數(shù)字(單位為角度)的雙曲正弦值。
- Math.cosh() - 函數(shù)返回?cái)?shù)值的雙曲余弦函數(shù)。
- Math.tanh() - 函數(shù)將會(huì)返回一個(gè)數(shù)的雙曲正切函數(shù)值。
- Math.asinh() - 函數(shù)返回給定數(shù)字的反雙曲正弦值。
- Math.acosh() - 返回一個(gè)數(shù)字的反雙曲余弦值。
- Math.atanh() - 函數(shù)返回一個(gè)數(shù)值反雙曲正切值。
Math.trunc()
Math.trunc() 方法會(huì)將數(shù)字的小數(shù)部分去掉,只保留整數(shù)部分,是一個(gè)取整操作。
Math 中有三個(gè)方法: Math.floor()
、Math.ceil()
、Math.round()
,也是用于取整操作。
Math.floor()
向下取整;Math.ceil()
向上取整;Math.round()
進(jìn)行四舍五入操作。Math.trunc()
去除小數(shù)部分,只保留整數(shù)部分。
const sample = Math.trunc(4.9); // 去掉小數(shù)位保留整數(shù)位const sample1 = Math.trunc(4.4); // 其它數(shù)據(jù)類型先調(diào)用Number轉(zhuǎn)化為數(shù)值類型const sample2 = Math.trunc(12.a); // 不能正確轉(zhuǎn)化為數(shù)值類型返回NaNconsole.log(sample, sample1,sample2); // 4, 4 ,NaN
Math.sign()
Math.sign()
判斷一個(gè)數(shù)到底是正數(shù)、負(fù)數(shù)、還是零。對(duì)于非數(shù)值,會(huì)先將其轉(zhuǎn)換為數(shù)值。
5種返回值, 分別是 1, -1, 0, -0, NaN
. 代表的各是正數(shù), 負(fù)數(shù), 正零, 負(fù)零, NaN
。
- 參數(shù)為正數(shù),返回+1;
- 參數(shù)為負(fù)數(shù),返回-1;
- 參數(shù)為 0,返回0;
- 參數(shù)為-0,返回-0;
- 其他值,返回NaN。
const sample = Math.sign(-4); // -1 負(fù)數(shù)const sample1 = Math.sign(4); // 1 正數(shù)const sample2 = Math.sign(0); // 0 0const sample3 = Math.sign(-0); // -0 -0const sample4 = Math.sign(a); // NaN 非數(shù)值console.log(sample, sample1, sample2, sample3, sample4); // -1, 1, 0, -0, NaN
Math.cbrt()
在數(shù)學(xué)上 : 如果x3=a,那么x叫做a的立方根。Math.cbrt()
計(jì)算一個(gè)數(shù)的立方根
const sample = Math.cbrt(-1);const sample1 = Math.cbrt(8);const sample2 = Math.cbrt(0); // 0的立方根是0const sample3 = Math.cbrt(-0);const sample4 = Math.cbrt(a); // 非數(shù)值類型先調(diào)用Number轉(zhuǎn)化為數(shù)值類型console.log(sample, sample1, sample2, sample3, sample4); // -1, 2, 0, -0, NaN
Math.clz32()
Math.clz32()
函數(shù)返回參數(shù)轉(zhuǎn)化為 32 位無符號(hào)整數(shù)數(shù)字二進(jìn)制 開頭的 0 的個(gè)數(shù),
對(duì)于空值或其他類型的值,Math.clz32
方法會(huì)將它們先轉(zhuǎn)為數(shù)值,然后再計(jì)算。
注意
Math.clz32()
對(duì)于小數(shù),只考慮整數(shù)部分<<
運(yùn)算符把 【要位移的數(shù)字】 的所有位向左移 【位移位數(shù)】 指定的位數(shù)。- result =【要位移的數(shù)字】 << 【位移位數(shù)】
const sample = Math.clz32(); // 空轉(zhuǎn)化為數(shù)值為 0 const sample1 = Math.clz32(1 << 29); // 左位移運(yùn)算符改變const sample2 = Math.clz32(44.7); // 只考慮整數(shù)部分const sample3 = Math.clz32(true); // 轉(zhuǎn)化為數(shù)值為 1 const sample4 = Math.clz32(a); // 非數(shù)值類型先調(diào)用Number轉(zhuǎn)化為數(shù)值類型console.log(sample, sample1, sample2, sample3, sample4); // 32, 2, 26, 31, 32
Math.imul()
Math.imul()
方法將兩個(gè)參數(shù)分別轉(zhuǎn)換為 32 位整數(shù),相乘后返回 32 位的帶符號(hào)整數(shù)。
JavaScript 有精度限制,使得超過 2 的 53 次方的值無法精確表示。Math.imul()
方法可以返回正確的低位數(shù)值。
const sample = Math.imul(-1, 8.9); // 參數(shù)有小數(shù)會(huì)先轉(zhuǎn)化為整數(shù)const sample1 = Math.imul(0xffffffff, 5); // 下面的參數(shù)它們的乘積超過了 2 的 53 次方也能正確顯示const sample2 = Math.imul(0x7fffffff, 0x7fffffff); console.log(sample, sample1, sample2); // -8, -5, 1
Math.fround()
Math.fround() 可以將任意的數(shù)字轉(zhuǎn)換為32位單精度浮點(diǎn)數(shù)形式。
JavaScript 內(nèi)部使用64位的雙浮點(diǎn)數(shù)字,支持很高的精度。對(duì)于32位單精度格式來說,數(shù)值精度是24個(gè)二進(jìn)制位(1 位隱藏位與 23 位有效位)
注意
- 如果參數(shù)的絕對(duì)值大于224,返回的結(jié)果便開始丟失精度。
- 對(duì)于
NaN
和Infinity
,此方法返回原值 - 對(duì)于其它非數(shù)值,
Math.fround
方法先將其轉(zhuǎn)為數(shù)值,再返回單精度浮點(diǎn)數(shù)。
const sample = Math.fround(99); const sample1 = Math.fround(0.7); // 丟失精度const sample2 = Math.fround(5);const sample3 = Math.fround(Infinity);console.log(sample, sample1, sample2, sample3); // 輸出 99, 0.699999988079071, 5, Infinity
Math.hypot()
Math.hypot()
函數(shù)返回所有參數(shù)的平方和的平方根。
const sample = Math.hypot(3, 4); // 2*2 + 2*2 的平方根const sample1 = Math.hypot(); // 0 空轉(zhuǎn)化為數(shù)值為 0 const sample2 = Math.hypot(-9);const sample3 = Math.hypot(Infinity); // 非數(shù)值類型先轉(zhuǎn)化為數(shù)值類型const sample4 = Math.hypot(1, 2, a); // 只要有一個(gè)參數(shù)無法轉(zhuǎn)為數(shù)值,就會(huì)返回 NaN。console.log(sample, sample1, sample2, sample3, sample4); // 5, 0, 9, Infinity, NaN
對(duì)數(shù)方法
Math.expm1()
Math.expm1()
返回 e**x** - 1,即Math.exp(x) - 1
其中 x
是該函數(shù)的參數(shù), e
是自然對(duì)數(shù)的底數(shù)
const sample = Math.expm1(-38);const sample1 = Math.expm1(0);const sample2 = Math.expm1(1);const sample3 = Math.expm1(a);console.log(sample, sample1, sample2, sample3); // -1, 0, 1.718281828459045, NaN
Math.log1p()
Math.log1p()
方法返回參數(shù) + 1 后的自然對(duì)數(shù),(底為 e),即Math.log(1 + x)
。
const sample = Math.log1p(-2); // 參數(shù)小于 -1 返回 NaNconst sample1 = Math.log1p(-1); // -1 + 1 = 0 返回 - Infinity 0沒有對(duì)數(shù)const sample2 = Math.log1p(0); // 0 + 1 = 1 1 的對(duì)數(shù)是 0const sample3 = Math.log1p(a);console.log(sample, sample1, sample2, sample3); // NaN, -Infinity, 0, NaN
Math.log10()
Math.log10()
返回以 10 為底的參數(shù)對(duì)數(shù)
const sample = Math.log10(-2); // 參數(shù)小于 0 返回 NaNconst sample1 = Math.log10(1); // 1 的對(duì)數(shù)是 0const sample2 = Math.log10(10); // 轉(zhuǎn)化為數(shù)值類型const sample3 = Math.log10(a);console.log(sample, sample1, sample2, sample3); // NaN, 0, 1, NaN
Math.log2()
Math.log10()
和 Math.log2()
類似,一個(gè)以 10 為底,一個(gè)以 2 為底Math.log2()
返回以 2 為底的參數(shù)對(duì)數(shù)
const sample = Math.log2(-2); // 參數(shù)小于 0 返回 NaNconst sample1 = Math.log2(1); // 1 的對(duì)數(shù)是 0const sample2 = Math.log2(1024); // 轉(zhuǎn)化為數(shù)值類型const sample3 = Math.log2(a);console.log(sample, sample1, sample2, sample3); // NaN, 0, 10, NaN
雙曲函數(shù)方法
ES6 新增了 6 個(gè)雙曲函數(shù)方法。
Math.sinh()
函數(shù)返回一個(gè)數(shù)字(單位為角度)的雙曲正弦值。Math.cosh()
函數(shù)返回?cái)?shù)值的雙曲余弦函數(shù), 可用constant e表示。Math.tanh()
函數(shù)將會(huì)返回一個(gè)數(shù)的雙曲正切函數(shù)值。Math.asinh()
函數(shù)返回給定數(shù)字的反雙曲正弦值。Math.acosh()
返回一個(gè)數(shù)字的反雙曲余弦值。Math.atanh()
函數(shù)返回一個(gè)數(shù)值反雙曲正切值。
BigInt 數(shù)據(jù)類型
描述
ES2020 引入了一種新的數(shù)據(jù)類型 BigInt
,這是 ECMAScript 的第八種數(shù)據(jù)類型。BigInt
只用來表示整數(shù),沒有位數(shù)的限制,任何位數(shù)的整數(shù)都可以精確表示。BigInt
數(shù)據(jù)類型的目的是比Number
數(shù)據(jù)類型支持的范圍更大的整數(shù)值。
注意
- BigInt 也可以使用各種進(jìn)制表示,都要加上后綴 n 。
- BigInt 與Number 數(shù)值的類型不同。
- BigInt 除一元加號(hào)(+)運(yùn)算符外,BigInt 可以使用所有運(yùn)算符。
- BigInt 也可以轉(zhuǎn)化為其它數(shù)據(jù)類型。
- BigInt 不能與普通數(shù)值進(jìn)行混合運(yùn)算。
const sample = 99999999999999999999n; // 可以表示任意長(zhǎng)度的整數(shù)const sample1 = 999n + 999n * 99n / 99n - 99n; // 可以使用除一元加號(hào)外所有運(yùn)算符const sample2 = 0o777n + 0b1101n; // 可以使用各種進(jìn)制來表示const sample3 = String(1n); // 轉(zhuǎn)化為其他類型數(shù)據(jù) n會(huì)消失console.log(sample); // 99999999999999999999nconsole.log(sample1); // 1899nconsole.log(sample2); // 524nconsole.log(sample3); // 1const sample4 = 10n + 10; // 直接報(bào)錯(cuò) 不能與普通數(shù)值進(jìn)行混合運(yùn)算。
BigInt 函數(shù)
JavaScript 原生提供 BigInt
函數(shù),將其他類型的值轉(zhuǎn)為 BigInt
類型。 與 Number()
一致
注意
- 參數(shù)不能為空。
- 參數(shù)不能為小數(shù)。
- 參數(shù)必須能正常轉(zhuǎn)化為數(shù)值。
const sample = BigInt(44); const sample1 = BigInt(490); // 可以正確轉(zhuǎn)換console.log(sample); // 44nconsole.log(sample1); // 490n// 下面全部報(bào)錯(cuò)const sample2 = BigInt(undefined);const sample3 = BigInt(44a); // 轉(zhuǎn)化為數(shù)值為 NaNconst sample4 = BigInt(1.1); // 參數(shù)為小數(shù)報(bào)錯(cuò)const sample5 = BigInt(); // 為空