localstorage 是 html5 規範中作為持久化儲存客戶端資料的方案,localstorage 可以用於資料快取,日誌儲存等應用場景。由於 localstorage 本身的一些特性:
使用好 localstorage 並沒有那麼簡單,本文主要介紹其使用的一些最佳實踐。
由於瀏覽器對於新特性支援的速度和使用者瀏覽器的版本不同,在使用 localstorage 之前,需要先通過嗅探操作判斷當前環境是否支援:
function islocalstorageusable()
localstorage.removeitem(localstoragetestkey);
return issupport;
} catch(e)
}
讀寫操作雖然可以用來驗證當前瀏覽器是否支援 localstorage 特性,但是並非支援 localstorage 的瀏覽器一定可以進行寫操作,前面已經提到「瀏覽器給 localstorage 分配的儲存空間是有限的」,當儲存的內容已經到達上限,則無法再進行寫操作。
try
localstorage.removeitem(localstoragetestkey);
return issupport;
} catch(e) else
return issupport;
}
// 類的例項方法
ready()
if (this.issupport)
return promise.reject();
}
通過定義上述的 ready 方法,使得嗅探方法具備「惰性執行」的特性。
當將物件直接作為鍵值對傳入 localstorage 時,會隱式呼叫 tostring 方法:
// 最終儲存的鍵值為 key:[object object] value: [object object]
localstorage.setitem({}, {});
如果不注意鍵名的型別,可能會出現因鍵名重複而造成資料丟失的問題。
當 localstorage 的 key 為物件時,應該給予適當的警告提示,一定程度上避免低階錯誤導致的 bug:
function normalizekey(key) used as a key, but it is not a string.`);
key = string(key);
}return key;
}
對於 value,如果這樣處理,則使得儲存的值沒有什麼意義,所以需要根據資料的型別進行序列化和反序列化處理。
當呼叫 setitem 方法向 localstorage 中儲存值時,需要對儲存的值進行統一的序列化處理:
// 類的例項方法
setitem(key, value)
serialize(value, (error, valuestring) =>
try catch(e)
})})
}
一般情況下,儲存的都是 json 格式的資料,利用 json.stringify 進行序列化處理:
function serialize(value, callback) catch(e)
}
這裡需要對 json.stringify 方法進行異常捕獲,「當序列化的物件存在迴圈引用時,該方法會丟擲異常」。反序列化處理時,同樣需要對 json.parse 進行異常捕獲,比較常見的錯誤:
json.parse('undefined');
// vm20179:1 uncaught syntaxerror: unexpected token u in json at position 0
針對這種情況,可以在 setitem 方法中做一層過濾處理:
if (value === undefined)
但是也不能完全避免掉非法的 json 字串,所以仍需要利用 try/catch 捕獲異常。
如果業務需求比較複雜,那麼需要通過判斷儲存值的具體型別來進行特定的序列化處理:
const tostring = object.prototype.tostring;
function serialize(value, callback)
filereader.readasarraybuffer(value);
break;
default:
try catch(e) }}
這裡增加了 blob 型別的儲存需求,需要利用 filereader + arraybuffer 將其序列化,另外需要識別符號來告訴反序列化過程中該值的型別。
json.stringify 方法在執行的過程中(執行時)需要分析物件的結構以及鍵值對的型別,這在處理複雜巢狀物件時是非常耗時的。
優化的手段實際上就是將這部分耗時的工作提到編譯階段,舉個例子:
const testobj =
function stringify() ","lastname":"$","age":$}"`
}
const benchmark = require('benchmark');
const fastjson = require('fast-json-stringify');
const suite = new benchmark.suite();
const testobj =
function stringify() ","lastname":"$","age":$}"`
} suite.add('json.stringify obj', function () )
suite.add('fast-json-stringify obj', function () )
suite.on('cycle', (e) => console.log(e.target.tostring()))
.on('complete', function() `);
})suite.run()
得到的測試結果表明:無論是每秒執行測試**的次數還是相對最快速度的統計誤差,優化方案表現得更好。
# 測試結果
json.stringify obj x 1,695,618 ops/sec ±0.62% (90 runs sampled)
fast-json-stringify obj x 787,253,287 ops/sec ±0.36% (92 runs sampled)
fastest is fast-json-stringify obj
上述例子不具備通用性,在實際的業務開發中,可以利用自定義 json schema 來生成特定的 stringify 方法,有成熟的開源框架供選擇:
localstorage 是受同源策略限制的,這種隔離級別相當於是應用級別的,但是在實際的業務開發過程中,這種隔離級別部分場景是覆蓋不到的。
向 localstorage 中儲存鍵值對時,主要有以下特點:
如果當前應用中各個模組都有採用 localstorage 儲存資料的需求,那麼怎麼從模組級別去隔離呢?
因為鍵值對都是通過鍵名來索引,所以可以為鍵名加上命名空間來區分:
const keyprefix = name + '/';
localstorage.setitem(keyprefix + key, value);
在多儲存模組的情況下,直接呼叫 clear 方法會出現誤刪其它儲存模組資料的問題,引入命名空間之後,可以避免這樣的情況:
function clear(keyprefix) })}
你點的每個贊,我都認真當成了喜歡 localstorage原理與使用
首先自然是檢測瀏覽器是否支援本地儲存。在html5中,本地儲存是乙個window的屬性,包括localstorage和sessionstorage,從名字應該可以很清楚的辨認二者的區別,前者是一直存在本地的,後者只是伴隨著session,視窗一旦關閉就沒了。二者用法完全相同,這裡以localstor...
本地快取localstorage使用
最近做專案遇到乙個問題,即從 個人中心 點選進入 修改支付寶 需要自動獲取使用者手機號怎麼做?修改支付寶的api不提供使用者手機號資料,但是發現個人中心提供,於是想通過localstorage在個人中心頁面獲取到手機號然後儲存在本地快取,進入修改支付寶頁面後再獲取出來。經簡單查詢用法和實驗,如下 v...
資料儲存localStorage的使用方法
初始化資料庫。如果路徑為空,它將建立乙個記憶體資料庫 void localstorageinit const char fullpath 釋放分配的資源 void localstoragefree 設定儲存內容 void localstoragesetitem const char key,cons...