In Jurassic Park, we need to save visitor preferences, security settings, and temporary session data on the client side. JavaScript provides two built-in storage mechanisms: localStorage and sessionStorage — both letting us store key-value pairs in the browser without needing a server.
| Feature | localStorage | sessionStorage | |---------|-------------|----------------| | Persistence | Survives browser close/reopen | Cleared when tab/window closes | | Scope | Shared across all tabs/windows of the same origin | Isolated to the current tab | | Storage limit | ~5-10 MB per origin | ~5-10 MB per tab | | Use case | User preferences, settings | Temporary session data, form state |
1// setItem — save data
2localStorage.setItem('parkTheme', 'dark');
3localStorage.setItem('language', 'en');
4sessionStorage.setItem('currentSector', 'B-4');
5
6// getItem — read data
7const theme = localStorage.getItem('parkTheme'); // "dark"
8const missing = localStorage.getItem('nothere'); // null
9
10// removeItem — delete a key
11localStorage.removeItem('parkTheme');
12
13// clear — delete all data
14localStorage.clear();
15
16// length and key() — iterate
17console.log(localStorage.length); // number of items
18for (let i = 0; i < localStorage.length; i++) {
19 const key = localStorage.key(i);
20 console.log(key, localStorage.getItem(key));
21}Web Storage only stores strings, so for objects and arrays we use JSON:
1// Storing an object
2const userPrefs = {
3 theme: 'dark',
4 fontSize: 16,
5 language: 'en',
6 notifications: { security: true, feeding: true }
7};
8
9localStorage.setItem('userPreferences', JSON.stringify(userPrefs));
10
11// Reading back
12const storedPrefs = JSON.parse(localStorage.getItem('userPreferences'));
13console.log(storedPrefs.theme); // "dark"
14
15// Storing an array
16const recentIncidents = ['INC-001', 'INC-002', 'INC-003'];
17localStorage.setItem('recentIncidents', JSON.stringify(recentIncidents));
18
19const incidents = JSON.parse(localStorage.getItem('recentIncidents') || '[]');1class UserPreferences {
2 constructor() {
3 this.storageKey = 'jurassicParkPrefs';
4 this.defaults = {
5 theme: 'light',
6 language: 'en',
7 alertSound: true,
8 mapZoom: 2,
9 favoriteSection: 'overview'
10 };
11 }
12
13 get(key) {
14 const stored = localStorage.getItem(this.storageKey);
15 const prefs = stored ? JSON.parse(stored) : {};
16 return key in prefs ? prefs[key] : this.defaults[key];
17 }
18
19 set(key, value) {
20 const stored = localStorage.getItem(this.storageKey);
21 const prefs = stored ? JSON.parse(stored) : {};
22 prefs[key] = value;
23 localStorage.setItem(this.storageKey, JSON.stringify(prefs));
24 }
25
26 setMultiple(updates) {
27 const stored = localStorage.getItem(this.storageKey);
28 const prefs = stored ? JSON.parse(stored) : {};
29 Object.assign(prefs, updates);
30 localStorage.setItem(this.storageKey, JSON.stringify(prefs));
31 }
32
33 reset() {
34 localStorage.removeItem(this.storageKey);
35 }
36
37 getAll() {
38 const stored = localStorage.getItem(this.storageKey);
39 const prefs = stored ? JSON.parse(stored) : {};
40 return { ...this.defaults, ...prefs };
41 }
42}
43
44const prefs = new UserPreferences();
45prefs.set('theme', 'dark');
46prefs.set('alertSound', false);
47console.log(prefs.get('theme')); // "dark"
48console.log(prefs.getAll()); // All preferences with defaults1class DataCache {
2 constructor(storage = localStorage, defaultTtlMs = 5 * 60 * 1000) {
3 this.storage = storage;
4 this.defaultTtlMs = defaultTtlMs;
5 }
6
7 set(key, value, ttlMs = this.defaultTtlMs) {
8 const item = {
9 value,
10 expiresAt: Date.now() + ttlMs
11 };
12 this.storage.setItem(`cache:${key}`, JSON.stringify(item));
13 }
14
15 get(key) {
16 const stored = this.storage.getItem(`cache:${key}`);
17 if (!stored) return null;
18
19 const item = JSON.parse(stored);
20
21 if (Date.now() > item.expiresAt) {
22 this.storage.removeItem(`cache:${key}`);
23 return null; // Expired
24 }
25
26 return item.value;
27 }
28
29 getOrFetch(key, fetchFn, ttlMs) {
30 const cached = this.get(key);
31 if (cached !== null) return Promise.resolve(cached);
32
33 return fetchFn().then(value => {
34 this.set(key, value, ttlMs);
35 return value;
36 });
37 }
38
39 clear(prefix) {
40 const keysToRemove = [];
41 for (let i = 0; i < this.storage.length; i++) {
42 const key = this.storage.key(i);
43 if (key && key.startsWith(`cache:${prefix || ''}`)) {
44 keysToRemove.push(key);
45 }
46 }
47 keysToRemove.forEach(key => this.storage.removeItem(key));
48 }
49}
50
51// Usage
52const cache = new DataCache(localStorage, 10 * 60 * 1000); // 10 min TTL
53
54async function getDinosaurData(id) {
55 return cache.getOrFetch(
56 `dino:${id}`,
57 () => fetch(`/api/dinosaurs/${id}`).then(r => r.json()),
58 5 * 60 * 1000 // 5 minutes
59 );
60}IMPORTANT — never store sensitive data in Web Storage:
Web Storage is accessible from any JavaScript on the page, making it vulnerable to XSS attacks.
Web Storage is a simple, convenient client-side storage mechanism: