summaryrefslogtreecommitdiff
path: root/src/content/en/tils/2021/08/11/js-bigint-reviver.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/en/tils/2021/08/11/js-bigint-reviver.adoc')
-rw-r--r--src/content/en/tils/2021/08/11/js-bigint-reviver.adoc89
1 files changed, 0 insertions, 89 deletions
diff --git a/src/content/en/tils/2021/08/11/js-bigint-reviver.adoc b/src/content/en/tils/2021/08/11/js-bigint-reviver.adoc
deleted file mode 100644
index 98ee79b..0000000
--- a/src/content/en/tils/2021/08/11/js-bigint-reviver.adoc
+++ /dev/null
@@ -1,89 +0,0 @@
-= Encoding and decoding JavaScript BigInt values with reviver
-:updatedat: 2021-08-13
-
-:reviver-fn: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#using_the_reviver_parameter
-:bigint: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
-:json-rfc: https://datatracker.ietf.org/doc/html/rfc8259
-
-`JSON.parse()` accepts a second parameter: a {reviver-fn}[`reviver()` function].
-It is a function that can be used to transform the `JSON` values as they're
-being parsed.
-
-As it turns out, when combined with JavaScript's {bigint}[`BigInt`] type, you
-can parse and encode JavaScript `BigInt` numbers via JSON:
-
-[source,javascript]
-----
-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 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 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:
-
-[source,javascript]
-----
-BigInt.prototype.toJSON = function() {
- return this.toString() + "n";
-};
-----
-
-With both `bigIntReviver` and `toJSON` defined, we can now successfully parse
-and encode JavaScript objects with `BigInt` values transparently:
-
-[source,javascript]
-----
-const s = `[
- null,
- true,
- false,
- -1,
- 3.14,
- "a string",
- { "a-number": "-123" },
- { "a-bigint": "-123n" }
-]`;
-
-const parsed = JSON.parse(s, bigIntReviver);
-const s2 = JSON.stringify(parsed);
-
-console.log(parsed);
-console.log(s2);
-
-console.log(typeof parsed[6]["a-number"])
-console.log(typeof parsed[7]["a-bigint"])
-----
-
-The output of the above is:
-
-[source,javascript]
-----
-[
- 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
-----
-
-If you're on a web browser, you can probably try copying and pasting the above
-code on the console right now, as is.
-
-Even though {json-rfc}[`JSON`] doesn't include `BigInt` number, encoding and
-decoding them as strings is quite trivial on JavaScript.