JavaScript Development Space

How to Elegantly Rewrite localStorage and sessionStorage Methods

In front-end development, localStorage and sessionStorage are common tools for client-side data storage. However, certain business requirements—such as encryption, global monitoring, or preventing unauthorized access—may necessitate customizing their behavior. This article details how to rewrite these methods elegantly while retaining their native functionality.

Why Rewrite localStorage and sessionStorage?

Here are scenarios where rewriting can be beneficial:

  1. Business Customization: Add logic for specific keys, like encryption or validation.
  2. Global Monitoring: Track access logs and operation frequency.
  3. Data Protection: Safeguard critical keys from unauthorized modifications.

Core Approach

1. Retain Native Methods

Store references to the original methods:

js
1 const _setItem = localStorage.setItem;
2 const _getItem = localStorage.getItem;

2. Proxy Methods

Rewrite the methods to include custom logic:

js
1 localStorage.setItem = function (key, value) {
2 if (key === 'protectedKey') return; // Prevent modifications
3 _setItem.call(this, key, value);
4 };
5
6 localStorage.getItem = function (key) {
7 return key === 'protectedKey'
8 ? 'Access denied'
9 : _getItem.call(this, key);
10 };

Flexible Configuration with Hooks

Introduce hooks for customization:

js
1 function proxyStorage(storage, config = {}) {
2 const { beforeSetItem = (k, v) => [k, v], afterGetItem = (k, v) => v } = config;
3 const _setItem = storage.setItem;
4 const _getItem = storage.getItem;
5
6 storage.setItem = function (key, value) {
7 const [newKey, newValue] = beforeSetItem(key, value);
8 _setItem.call(this, newKey, newValue);
9 };
10
11 storage.getItem = function (key) {
12 const value = _getItem.call(this, key);
13 return afterGetItem(key, value);
14 };
15 }

Examples of Usage:

  1. Encrypt Data: Use a library like CryptoJS to encrypt and decrypt stored data.
  2. Log Operations: Record all setItem and getItem calls.
  3. Intercept Keys: Block access to specific keys.

Encapsulation with Singleton Class

Encapsulate the proxy logic in a singleton class for ease of use:

js
1 class StorageProxy {
2 constructor(storage, config) {
3 if (StorageProxy.instance) return StorageProxy.instance;
4 this.init(storage, config);
5 StorageProxy.instance = this;
6 }
7
8 init(storage, config) {
9 this.storage = storage;
10 this.originalSetItem = storage.setItem;
11 this.originalGetItem = storage.getItem;
12 this.config = config;
13
14 this.proxy();
15 }
16
17 proxy() {
18 const { storage, config: { beforeSetItem, afterGetItem } } = this;
19
20 storage.setItem = (key, value) => {
21 const [k, v] = beforeSetItem(key, value);
22 this.originalSetItem.call(storage, k, v);
23 };
24
25 storage.getItem = (key) => {
26 const value = this.originalGetItem.call(storage, key);
27 return afterGetItem(key, value);
28 };
29 }
30
31 unproxy() {
32 this.storage.setItem = this.originalSetItem;
33 this.storage.getItem = this.originalGetItem;
34 }
35 }

Summary

Rewriting localStorage and sessionStorage allows for powerful business logic integration, enhanced security, and better data management. Encapsulate this functionality into reusable classes or modules to make your projects more maintainable and secure.

JavaScript Development Space

© 2025 JavaScript Development Space - Master JS and NodeJS. All rights reserved.