I'm sorry, but this code makes no sense and is frankly confusing and dangerous.
It doesn't really add any convenience over just using window.localStorage directly, besides the JSON conversion.
This can be achieved with just
exportclassJSONStorage{constructor(storage){if(!storage||typeofstorage!=="object")thrownewError(`Expected a Storage object, got ${storage}`)this.storage=storage}set(k,v){conststr=JSON.stringify(v)if(typeofstr==="undefined")returnthis.storage.removeItem(k)this.storage.setItem(k,v)}get(k){conststr=this.storage.getItem(k)// we return `undefined` instead of `null`, so that we can differentiate between the cases when the key doesn't exist vs when the value is a JSON-serialized `"null"`if(str===null)returnreturnJSON.parse(str)}remove(k){this.storage.removeItem(k)}}
you can try it as follows
consta=newJSONStorage(window.localStorage)constb=newJSONStorage(window.sessionStorage)a.set("1",1)b.set("1",2)// notice that keys are coerced to string automatically, and we get back deserialized numbers, not stringsa.get(1)// 1b.get(1)// 2
Instead, the provided code:
checks if localStorage is supported on every action, instead of just once.
calls .getItem(key) twice, which might be the most expensive operation here, short of setItem
similarly, calls getItem before removeItem
since !"" is true, empty values (if created outside this interface) will never be removed!
uses a mutable field data on the singleton object instead of a local variable. This data never needs to survive beyond a function call, and is being reused by all accesses to Storage.
constructs a {key, data} object with the function's arguments, which will never be used and doesn't offer any ergonomic benefit.
declares a function to just set null to this.data.
on most error conditions (such as passing a number as key, because numbers don't have .length), randomly returns the contents of this.data, which will always be null because every method, even remove that doesn't use it first calls clearData. This is confusing, since the standard getItem returns null for missing key, and "null" is a valid JSON string.
makes an object instance named Storage to then just export it as default, instead of exporting the individual functions, avoiding a layer of indentation.
PS: Keep in mind, my code still doesn't prevent you from calling, say, b.set() which would create a undefined => undefined entry, which would cause a JSON SyntaxError when calling b.get(), nor does it exhaustively check for the storage object passed to the constructor having the necessary methods.
Edit: The former is quite serious, so I fixed it now. This now removes the key, so setting a value of undefined and then getting it will, in fact, return undefined
I'm sorry, but this code makes no sense and is frankly confusing and dangerous.
It doesn't really add any convenience over just using
window.localStoragedirectly, besides theJSONconversion.This can be achieved with just
you can try it as follows
Instead, the provided code:
localStorageis supported on every action, instead of just once..getItem(key)twice, which might be the most expensive operation here, short ofsetItemgetItembeforeremoveItem!""istrue, empty values (if created outside this interface) will never be removed!dataon the singleton object instead of a local variable. Thisdatanever needs to survive beyond a function call, and is being reused by all accesses to Storage.{key, data}object with the function's arguments, which will never be used and doesn't offer any ergonomic benefit.nulltothis.data..length), randomly returns the contents ofthis.data, which will always benullbecause every method, evenremovethat doesn't use it first callsclearData. This is confusing, since the standardgetItemreturnsnullfor missing key, and"null"is a valid JSON string.Storageto then just export it asdefault, instead of exporting the individual functions, avoiding a layer of indentation.PS:
Keep in mind, my code still doesn't prevent you from calling, say,nor does it exhaustively check for theb.set()which would create aundefined => undefinedentry, which would cause a JSONSyntaxErrorwhen callingb.get(),storageobject passed to the constructor having the necessary methods.Edit: The former is quite serious, so I fixed it now. This now removes the key, so setting a value of
undefinedand then getting it will, in fact, returnundefinedThank you for the informative points :)