Created
July 3, 2026 06:11
-
-
Save dfkaye/091a4e9846b3a2df6e5677dbac9377ee to your computer and use it in GitHub Desktop.
test (rant): store an instance as JSON and revive it as an instance of the same class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 2 July 2026 | |
| // store an instance as JSON and revive it as an instance of the same class | |
| // I haven't written one of these in a couple years (2024). This one is in | |
| // response to an infuriatingly ignorant justification for using TypeScript | |
| // *because compiler* instead of the more pleasant and correct destructured | |
| // parameter pattern in class function definitions. | |
| // I don't know this person but too much ignorance goes unremarked nowadays | |
| // among so-called professional front-end web developers when it should be | |
| // combated and corrected. | |
| // The post in question: | |
| // https://taxorubio.com/blog/type-definitions-to-retrieve-objects-from-localstorage/ | |
| // This is my test, there are (or should be) many like it, but this | |
| // one is mine. There are two classes under scrutiny in the post. I take | |
| // liberties modifying them here to show you don't need a compiler or a | |
| // set of typedefs to accomplish the objective (save data from a widget instance, retrieve that data and revive as a new widget instance). | |
| // The modified Widget class demonstrates that what you really need are | |
| // destructured parameters, not values. The modified DB class demonstrates | |
| // the changes needed to enforce that pattern during storage and retrieval. | |
| ~(function() { | |
| class DB { | |
| constructor(storage) { | |
| this.storage = storage; | |
| // Map of constructors by storage key. | |
| // Yes, that makes two storage mechanisms to track instead of one. | |
| // This one lets us prevent modifying storage with mere values. | |
| this.map = new Map(); | |
| } | |
| get(key) { | |
| var constructor = this.map.get(key); | |
| // If we haven't mapped a constructor, we haven't stored an item | |
| // for this key. | |
| if (!constructor) { | |
| return console.error(`No item stored at key ${ key }`); | |
| } | |
| var json = this.storage.getItem(key); | |
| var value = JSON.parse(json); | |
| return new constructor(value); | |
| } | |
| set(key, data) { | |
| if (data !== Object(data)) { | |
| return console.error( | |
| `data must be an object, not a primitive, ${ data }` | |
| ); | |
| }; | |
| this.map.set(key, data.constructor); | |
| var json = JSON.stringify(data); | |
| return this.storage.setItem(key, json); | |
| } | |
| } | |
| class Widget { | |
| // what you really need are destructured parameters, not values | |
| constructor({ value }) { | |
| // This line is incomprehensibly missing from original example. | |
| this.value = parseFloat(value); | |
| } | |
| // I've added a private method to test from prototype method | |
| #test() { | |
| console.warn( | |
| "*private method test*", | |
| "\npublic value:", this.value | |
| ); | |
| } | |
| isEven() { | |
| // test private method call from prototype | |
| this.#test(); | |
| return this.value % 2 == 0; | |
| } | |
| } | |
| // The correct solution starts by requiring that our widget receive an | |
| // object to be destructured, not a value... | |
| var widget = new Widget({ value: "234" }); | |
| console.log("our widget:", "\nisEven:", widget.isEven(), "\nvalue:", widget.value); | |
| var group = "did it work?"; | |
| console.group(group); | |
| var db = new DB(localStorage); | |
| db.set("widget", widget); | |
| var restored = db.get("widget"); | |
| console.assert(restored.isEven(), "should work"); | |
| console.groupEnd(group); | |
| console.group("null"); | |
| var key = "dsaflk;jsdf;lkaseroiiauewrpaoesrfapojdsf"; | |
| console.assert( | |
| db.get(key) == null, | |
| `should return null for key "${ key }"` | |
| ); | |
| db.set(key, {value: key}); | |
| console.assert( | |
| db.get(key).value === key, | |
| `should return value for key "${ key }"` | |
| ); | |
| console.groupEnd("null"); | |
| })(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment