📜 ⬆️ ⬇️

Working with local storage as with an object - Continued

With this post, I would like to improve and suggest an adequate way to work with the repository, as with an object. Code from the post “ Working with local storage, as with an object? Easy! "I highly recommend not to use, everything is bad there (the disadvantages are set out below). The purpose of this - to explain to all those who added an article on the link to favorites or put a plus sign, never use this code .

Now I want to demonstrate the simplest idea suggested by Scalar in the commentary .

When the page loads (even before the DOM tree readiness event), we access the repository (in this case, it is localStorage and sessionStorage), get JSON, deserialize it and put it into some variable.
localObject = JSON.parse( localStorage.getItem( '_myStorage' ) ); // "{'a':1, 'b':2}" → {a:1, b:2} 

Then, every N milliseconds, perform the reverse process:
 localStorage.setItem( '_myStorage', JSON.stringify( localObject ) ); 

At the onbeforeunload event, do the same.
')
The implementation of the idea is simple (the level of complexity of the task is low and even a beginner is available). But, not everyone (including me) thought of that before.
ObjectStorage constructor code
 var ObjectStorage = function ObjectStorage( name, duration ) { var self, name = name || '_objectStorage', defaultDuration = 5000; //     ,       , //      , //   duration ( ) if ( ObjectStorage.instances[ name ] ) { self = ObjectStorage.instances[ name ]; self.duration = duration || self.duration; } else { self = this; self._name = name; self.duration = duration || defaultDuration; self._init(); ObjectStorage.instances[ name ] = self; } return self; }; ObjectStorage.instances = {}; ObjectStorage.prototype = { // type == local || session _save: function ( type ) { var stringified = JSON.stringify( this[ type ] ), storage = window[ type + 'Storage' ]; if ( storage.getItem( this._name ) !== stringified ) { storage.setItem( this._name, stringified ); } }, _get: function ( type ) { this[ type ] = JSON.parse( window[ type + 'Storage' ].getItem( this._name ) ) || {}; }, _init: function () { var self = this; self._get( 'local' ); self._get( 'session' ); ( function callee() { self.timeoutId = setTimeout( function () { self._save( 'local' ); callee(); }, self._duration ); })(); window.addEventListener( 'beforeunload', function () { self._save( 'local' ); self._save( 'session' ); }); }, //  ,     (clearTimeout( storage.timeoutId )) timeoutId: null, local: {}, session: {} }; 



Using:
 var storage = new ObjectStorage; storage.local = {a:4, b: {c:5}}; storage.session = {a:7, b: {c:8}}; b = storage.local.b; bc = {d:6}; 


Reload page,
 var storage = new ObjectStorage; console.log( storage ); /* { _name: ..., duration: ..., local: {a:4, b: {c: {d: 6}}}, session: {a:7, b: {c :8}} } */ 


Alternatively, when you call the ObjectStorage constructor, you can pass two arguments: name - the name of the key in the repository and duration - the interval for storing data in localStorage.
 new ObjectStorage( '_myStorage', 1000 ); 

You can leave the name standard:
 new ObjectStorage( null, 1000 ); 

And you can change the duration after initialization:
 var storage = new ObjectStorage; storage.duration = 2000; 

(you can change storage._name, but this is not recommended, I even put a wand, like a private property :))

Pros, compared with the decision on the link at the beginning of this article:


Common cons:


Of good.

Source: https://habr.com/ru/post/144998/


All Articles