摘要:意外四舍五入會損害程序的可靠性和安全性。下面是一些例子構造函數與其他基本類型一樣,可以使用構造函數創建。總結是一種新的數據類型,用于當整數值大于數據類型支持的范圍時。
為了保證的可讀性,本文采用意譯而非直譯。
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!
BigInt數據類型的目的是比Number數據類型支持的范圍更大的整數值。在對大整數執行數學運算時,以任意精度表示整數的能力尤為重要。使用BigInt,整數溢出將不再是問題。
此外,可以安全地使用更加準確時間戳,大整數ID等,而無需使用變通方法。 BigInt目前是第3階段提案, 一旦添加到規范中,它就是JS 第二個數字數據類型,也將是 JS 第8種基本數據類型:
Boolean
Null
Undefined
Number
BigInt
String
Symbol
Object
在本文中,咱們將詳細介紹BigInt,看看它如何解決使用Number類型的限制。
問題對于學過其他語言的程序員來說,JS中缺少顯式整數類型常常令人困惑。許多編程語言支持多種數字類型,如浮點型、雙精度型、整數型和雙精度型,但JS卻不是這樣。在JS中,按照IEEE 754-2008標準的定義,所有數字都以雙精度64位浮點格式表示。
在此標準下,無法精確表示的非常大的整數將自動四舍五入。確切地說,JS 中的Number類型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之間的整數,任何超出此范圍的整數值都可能失去精度。
console.log(9999999999999999); // → 10000000000000000
該整數大于JS Number 類型所能表示的最大整數,因此,它被四舍五入的。意外四舍五入會損害程序的可靠性和安全性。這是另一個例子:
// 注意最后一位的數字 9007199254740992 === 9007199254740993; // → true
JS 提供Number.MAX_SAFE_INTEGER常量來表示 最大安全整數,Number.MIN_SAFE_INTEGER常量表示最小安全整數:
const minInt = Number.MIN_SAFE_INTEGER; console.log(minInt); // → -9007199254740991 console.log(minInt - 5); // → -9007199254740996 // notice how this outputs the same value as above console.log(minInt - 4); // → -9007199254740996解決方案
為了解決這些限制,一些JS開發人員使用字符串類型表示大整數。 例如,Twitter API 在使用 JSON 進行響應時會向對象添加字符串版本的 ID。 此外,還開發了許多庫,例如 bignumber.js,以便更容易地處理大整數。
使用BigInt,應用程序不再需要變通方法或庫來安全地表示Number.MAX_SAFE_INTEGER和Number.Min_SAFE_INTEGER之外的整數。 現在可以在標準JS中執行對大整數的算術運算,而不會有精度損失的風險。
要創建BigInt,只需在整數的末尾追加n即可。比較:
console.log(9007199254740995n); // → 9007199254740995n console.log(9007199254740995); // → 9007199254740996
或者,可以調用BigInt()構造函數
BigInt("9007199254740995"); // → 9007199254740995n
BigInt文字也可以用二進制、八進制或十六進制表示
// binary console.log(0b100000000000000000000000000000000000000000000000000011n); // → 9007199254740995n // hex console.log(0x20000000000003n); // → 9007199254740995n // octal console.log(0o400000000000000003n); // → 9007199254740995n // note that legacy octal syntax is not supported console.log(0400000000000000003n); // → SyntaxError
請記住,不能使用嚴格相等運算符將BigInt與常規數字進行比較,因為它們的類型不同:
console.log(10n === 10); // → false console.log(typeof 10n); // → bigint console.log(typeof 10); // → number
相反,可以使用等號運算符,它在處理操作數之前執行隱式類型轉換
console.log(10n == 10); // → true
除一元加號(+)運算符外,所有算術運算符都可用于BigInt
10n + 20n; // → 30n 10n - 20n; // → -10n +10n; // → TypeError: Cannot convert a BigInt value to a number -10n; // → -10n 10n * 20n; // → 200n 20n / 10n; // → 2n 23n % 10n; // → 3n 10n ** 3n; // → 1000n const x = 10n; ++x; // → 11n --x; // → 9n
不支持一元加號(+)運算符的原因是某些程序可能依賴于+始終生成Number的不變量,或者拋出異常。 更改+的行為也會破壞asm.js代碼。
當然,與BigInt操作數一起使用時,算術運算符應該返回BigInt值。因此,除法(/)運算符的結果會自動向下舍入到最接近的整數。例如:
25 / 10; // → 2.5 25n / 10n; // → 2n隱式類型轉換
因為隱式類型轉換可能丟失信息,所以不允許在bigint和 Number 之間進行混合操作。當混合使用大整數和浮點數時,結果值可能無法由BigInt或Number精確表示。思考下面的例子:
(9007199254740992n + 1n) + 0.5
這個表達式的結果超出了BigInt和Number的范圍。小數部分的Number不能精確地轉換為BigInt。大于2^53的BigInt不能準確地轉換為數字。
由于這個限制,不可能對混合使用Number和BigInt操作數執行算術操作。還不能將BigInt傳遞給Web api和內置的 JS 函數,這些函數需要一個 Number 類型的數字。嘗試這樣做會報TypeError錯誤
10 + 10n; // → TypeError Math.max(2n, 4n, 6n); // → TypeError
請注意,關系運算符不遵循此規則,如下例所示:
10n > 5; // → true
如果希望使用BigInt和Number執行算術計算,首先需要確定應該在哪個類型中執行該操作。為此,只需通過調用Number()或BigInt()來轉換操作數:
BigInt(10) + 10n; // → 20n // or 10 + Number(10n); // → 20
當 Boolean 類型與BigInt 類型相遇時,BigInt的處理方式與Number類似,換句話說,只要不是0n,BigInt就被視為truthy的值:
if (5n) { // 這里代碼塊將被執行 } if (0n) { // 這里代碼塊不會執行 }
排序BigInts和Numbers數組時,不會發生隱式類型轉換:
const arr = [3n, 4, 2, 1n, 0, -1n]; arr.sort(); // → [-1n, 0, 1n, 2, 3n, 4]
位操作符如|、&、<<、>>和^對Bigint的操作方式與Number類似。下面是一些例子
90 | 115; // → 123 90n | 115n; // → 123n 90n | 115; // → TypeErrorBigInt構造函數
與其他基本類型一樣,可以使用構造函數創建BigInt。傳遞給BigInt()的參數將自動轉換為BigInt:
BigInt("10"); // → 10n BigInt(10); // → 10n BigInt(true); // → 1n
無法轉換的數據類型和值會引發異常:
BigInt(10.2); // → RangeError BigInt(null); // → TypeError BigInt("abc"); // → SyntaxError
可以直接對使用構造函數創建的BigInt執行算術操作
BigInt(10) * 10n; // → 100n
使用嚴格相等運算符的操作數時,使用構造函數創建的Bigint與常規Bigint的處理方式類似
BigInt(true) === 1n; // → true庫函數
在撰寫本文時,Chrome +67 和Opera +54完全支持BigInt數據類型。不幸的是,Edge和Safari還沒有實現它。Firefox默認不支持BigInt,但是可以在about:config中將javascript.options.bigint 設置為true來開啟它,最新支持的情況可在“Can I use”上查看。
不幸的是,轉換BigInt是一個極其復雜的過程,這會導致嚴重的運行時性能損失。直接polyfill BigInt也是不可能的,因為該提議改變了幾個現有操作符的行為。目前,更好的選擇是使用JSBI庫,它是BigInt提案的純JS實現。
這個庫提供了一個與原生BigInt行為完全相同的API。下面是如何使用JSBI:
import JSBI from "./jsbi.mjs"; const b1 = JSBI.BigInt(Number.MAX_SAFE_INTEGER); const b2 = JSBI.BigInt("10"); const result = JSBI.add(b1, b2); console.log(String(result)); // → "9007199254741001"
使用JSBI的一個優點是,一旦瀏覽器支持,就不需要重寫代碼。 相反,可以使用babel插件自動將JSBI代碼編譯為原生 BigInt代碼。
總結BigInt是一種新的數據類型,用于當整數值大于Number數據類型支持的范圍時。這種數據類型允許我們安全地對大整數執行算術操作,表示高分辨率的時間戳,使用大整數id,等等,而不需要使用庫。
重要的是要記住,不能使用Number和BigInt操作數的混合執行算術運算,需要通過顯式轉換其中的一種類型。 此外,出于兼容性原因,不允許在BigInt上使用一元加號(+)運算符。
交流干貨系列文章匯總如下,覺得不錯點個Star,歡迎 加群 互相學習。
https://github.com/qq44924588...
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!
關注公眾號,后臺回復福利,即可看到福利,你懂的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106151.html
摘要:由于這個原因,在一些需要更精確運算的應用場景中,精度就不夠了,例如需要把位數字寫入到數組中。但是這又如何在中讀寫位數據操作中位數據的方案寫一個,在項目中引入,以下例子為使用方式與類似使用的得出的結果應該與原生方法保持一致的。 JS 的 Uint53 JS 的 Number 精度只有 「-2^52 ~ 2^52 - 1」,可以通過 Number.MAX_SAFE_INTEGER 查看 J...
摘要:作者陳大魚頭鏈接背景最近高級前端工程師劉小夕在上開了個每個工作日布一個前端相關題的,懷著學習的心態我也參與其中,以下為我的回答,如果有不對的地方,非常歡迎各位指出。 作者:陳大魚頭 github: KRISACHAN 鏈接:github.com/YvetteLau/S… 背景:最近高級前端工程師 劉小夕 在 github 上開了個每個工作日布一個前端相關題的 repo,懷著學習的心態我也參...
摘要:可能不會包括所有的語法提案。事實上,有些提案已經被擱置很多年了。因此,很可能也會在今年月份發布。 譯者按: 又過了1年... 原文:Whats New in JavaScript for 2019 譯者: Fundebug 為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用于學習。 最近這些年,ECMASCript標準發展節奏非常穩定,每年都會發布新的特...
摘要:引言發布了幾個新特性,主要變化是類型檢查更嚴格,對一些時髦功能拓展了類型支持。精讀這次改動意圖非常明顯,是為了跟上的新語法。基本可以算是對社區的回饋。討論地址是精讀新特性如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。 1 引言 Typescript 3.2 發布了幾個新特性,主要變化是類型檢查更嚴格,對 ES6、ES7 一些時髦功能拓展了類型支持。 2 概要 下面挑一...
摘要:詳情怎樣規避地獄作者先介紹什么是地獄,以及在開發過程中怎樣去規避地獄,一時爽性能問題火葬場。詳情其他亮點匯總開發者大會已于北京時間月日凌晨在美國山景城正式啟幕。 【前端】 1. JavaScript 的新數據類型:BigInt BigInt?是 JavaScript 中的一個新的數字基本(primitive)類型,可以用任意精度表示整數。使用?BigInt?可以安全地存儲和操作大整數,...
閱讀 1956·2021-11-22 15:29
閱讀 3252·2021-10-14 09:43
閱讀 1223·2021-10-08 10:22
閱讀 3342·2021-08-30 09:46
閱讀 1431·2019-08-30 15:55
閱讀 1923·2019-08-30 15:44
閱讀 849·2019-08-30 14:19
閱讀 1439·2019-08-30 13:13