From 036b70269074a67d8dc5122aed7ed56df044ce35 Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Fri, 13 Aug 2021 11:26:51 -0300 Subject: _tils/2021-08-11-encoding-and-decoding-javascript-bigint-values-with-reviver.md: Use regex to make the reviver dramatically simpler --- ...coding-javascript-bigint-values-with-reviver.md | 33 +++++++++------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/_tils/2021-08-11-encoding-and-decoding-javascript-bigint-values-with-reviver.md b/_tils/2021-08-11-encoding-and-decoding-javascript-bigint-values-with-reviver.md index f309641..d71174d 100644 --- a/_tils/2021-08-11-encoding-and-decoding-javascript-bigint-values-with-reviver.md +++ b/_tils/2021-08-11-encoding-and-decoding-javascript-bigint-values-with-reviver.md @@ -4,6 +4,8 @@ title: Encoding and decoding JavaScript BigInt values with reviver date: 2021-08-11 +updated_at: 2021-08-13 + layout: post lang: en @@ -24,19 +26,10 @@ and encode JavaScript `BigInt` numbers via JSON: [`BigInt`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt ```javascript -const bigIntReviver = (_, value) => { - if ( - typeof value === "string" - && value[value.length - 1] === "n" - && value.length > 1 - ) { - const numberStr = value.slice(0, value.length - 1); - if (numberStr.match(/^[0-9]+$/) !== null) { - return BigInt(numberStr); - } - } - return value; -}; +const bigIntReviver = (_, value) => + typeof value === "string" && value.match(/^-?[0-9]+n$/) + ? BigInt(value.slice(0, value.length - 1)) + : value; ``` I chose to interpret strings that contains only numbers and an ending `n` suffix @@ -44,8 +37,8 @@ as `BigInt` values, similar to how JavaScript interprets `123` (a number) differently from `123n` (a `bigint`); We do those checks before constructing the `BigInt` to avoid throwing needless -exceptions on the parsing function, as this could easily become a bottleneck -when parsing large JSON values. +exceptions and catching them on the parsing function, as this could easily +become a bottleneck when parsing large JSON values. In order to do the full roundtrip, we now only need the `toJSON()` counterpart: @@ -66,8 +59,8 @@ const s = `[ -1, 3.14, "a string", - { "a-number": "123" }, - { "a-bigint": "123n" } + { "a-number": "-123" }, + { "a-bigint": "-123n" } ]`; const parsed = JSON.parse(s, bigIntReviver); @@ -90,10 +83,10 @@ The output of the above is: -1, 3.14, 'a string', - { 'a-number': '123' }, - { 'a-bigint': 123n } + { 'a-number': '-123' }, + { 'a-bigint': -123n } ] -[null,true,false,-1,3.14,"a string",{"a-number":"123"},{"a-bigint":"123n"}] +[null,true,false,-1,3.14,"a string",{"a-number":"-123"},{"a-bigint":"-123n"}] string bigint ``` -- cgit v1.2.3