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.localStorage
directly, besides theJSON
conversion.This can be achieved with just
you can try it as follows
Instead, the provided code:
localStorage
is supported on every action, instead of just once..getItem(key)
twice, which might be the most expensive operation here, short ofsetItem
getItem
beforeremoveItem
!""
istrue
, empty values (if created outside this interface) will never be removed!data
on the singleton object instead of a local variable. Thisdata
never 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.null
tothis.data
..length
), randomly returns the contents ofthis.data
, which will always benull
because every method, evenremove
that doesn't use it first callsclearData
. This is confusing, since the standardgetItem
returnsnull
for missing key, and"null"
is a valid JSON string.Storage
to 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 => undefined
entry, which would cause a JSONSyntaxError
when callingb.get()
,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, returnundefined
Thank you for the informative points :)