如何給localStorage設置一個過時時間?

如何給localStorage設置一個有效期

引言

​  這個話題其實在上次分享<小程序填坑記裏講過了>已經講過(大佬可繞過哦~),但後來羣裏/評論都有些同窗,提到了一些疑問,問可否單獨整理一篇更爲詳細的分享,講解一下細節和完善提到的不足,如是有了下文👇。 —— 「 用心分享 作有溫度的攻城獅,我是首席填坑官——蘇南javascript

各位大佬早安,這裏是 @IT·平頭哥聯盟,我是 首席填坑官∙蘇南,用心分享 作有溫度的攻城獅。
公衆號: honeyBadger8,羣:912594095

思考點

​  從咱們接觸前端起,第一個熟悉的存儲相關的Cookie或者來分析咱們生活中密切相關的淘寶、物流、鬧鐘等事物來講起吧,前端

  • Cookie從你設置的時候,就會給個時間,不設置默認會話結束就過時;
  • 淘寶購物 從你下單付款起,就會給這件貨物設置一個收貨期限時間,過了這個時間自動認爲你收貨(即訂單結束);
  • 鬧鐘 你設置的提醒時間,其實也就是它的過時時間;
  • 再好比與您天天切身相關的產品需求,過完需求,你給出的上線時間,也就是這個需求的過時時間;
  • 再通俗點講,您今年的生日過完到明年生日之間也是至關於設置了有效期時間;
以上種種,咱們能得出一個結論任何一件事、一個行爲動做,都有一個時間、一個節點,甚至咱們能夠黑 localStorage,就是一個完善的API,爲何不能給一個設置過時的機制,由於 sessionStorageCookie並不能知足咱們實際的需求。

實現思路

  抱歉,黑localStorage不完善,有點誇張了,綜合上述的總結,問題就簡單了,給localStorage一個過時時間,一切就都so easy ?究竟是不是,來看看具體的實現吧:java

簡單回顧

//示例一:
localStorage.setItem('test',1234567);
let test = localStorage.getItem('test');
console.log(typeof test, test); 

//示例二:
localStorage['name'] = '蘇南';
console.log(localStorage['name']);
/*
輸出:
"1234567" ,'蘇南',
這裏要注意,1234567 存進去時是number 取出來就成string了
*/

重寫 set(存入) 方法:

  • 首先有三個參數 key、value、expired ,分別對應 鍵、值、過時時間,
  • 過時時間的單位能夠自由發揮,小時、分鐘、天均可以,
  • 注意點:存儲的值多是數組/對象,不能直接存儲,須要轉換 JSON.stringify
  • 這個時間如何設置呢?在這個值存入的時候在鍵(key)的基礎上擴展一個字段,如:key+'_expires_',而它的值爲當前 時間戳 + expired過時時間
  • 具體來看一下代碼
set(key, value, expired) {
    /*
    * set 存儲方法
    * @ param {String}     key 鍵
    * @ param {String}     value 值,
    * @ param {String}     expired 過時時間,以分鐘爲單位,非必須
    * @ 由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,交流:912594095
    */
    let source = this.source;
    source[key] = JSON.stringify(value);
    if (expired){
        source[`${key}__expires__`] = Date.now() + 1000*60*expired
    };
    return value;
}

重寫 get(獲取) 方法:

  • 獲取數據時,先判斷以前存儲的時間有效期,與當前的時間進行對比;
  • 但存儲時expired爲非必須參數,因此默認爲當前時間+1,即長期有效;
  • 若是存儲時有設置過時時間,且在獲取的時候發現已經小於當前時間戳,則執行刪除操做,並返回空值;
  • 注意點:存儲的值多是數組/對象,取出後不能直接返回,須要轉換 JSON.parse
  • 具體來看一下代碼
get(key) {
    /*
    * get 獲取方法
    * @ param {String}     key 鍵
    * @ param {String}     expired 存儲時爲非必須字段,因此有可能取不到,默認爲 Date.now+1
    * @ 由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,交流:912594095
    */
    const source = this.source,
    expired = source[`${key}__expires__`]||Date.now+1;
    const now = Date.now();

    if ( now >= expired ) {
        this.remove(key);
        return;
    }
    const value = source[key] ? JSON.parse(source[key]) : source[key];
    return value;
}

重寫 remove(刪除) 方法:

  • 刪除操做就簡單了,;
remove(key) {
    const data = this.source,
        value = data[key]; //首席填坑官∙蘇南的專欄
    delete data[key];
    delete data[`${key}__expires__`];
    return value;
}

優化點:

  • 記得上次有個同窗,是這麼評論的:「 刪除緩存能放到constructor裏面執行麼,放到get裏面 不取就一直在那是否是不太好?」;
  • 因此本次優化作一個初始化刪除操做,清除已通過期的數據;
  • 爲何不用for in而是 for ? for in循環遍歷對象的屬性時,原型鏈上的全部屬性都將被訪問,解決方案:使用hasOwnProperty方法過濾或Object.keys會返回自身可枚舉屬性組成的數組;
class storage {

    constructor(props) {
        this.props = props || {}
        this.source = this.props.source || window.localStorage
        this.initRun();
    }
    initRun(){
        /*
        * set 存儲方法
        * @ param {String}     key 鍵
        * @ param {String}     value 值,存儲的值多是數組/對象,不能直接存儲,須要轉換 JSON.stringify
        * @ param {String}     expired 過時時間,以分鐘爲單位
        * @ 由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,交流:912594095
        */
        const reg = new RegExp("__expires__");
        let data = this.source;
        let list = Object.keys(data);
        if(list.length > 0){
            list.map((key,v)=>{
                if( !reg.test(key )){
                    let now = Date.now();
                    let expires = data[`${key}__expires__`]||Date.now+1;
                    if (now >= expires ) {
                        this.remove(key);
                    };
                };
                return key;
            });
        };
    }
}

總結:

  以上就是今天爲你們總結的分享,您GET到了嗎?小程序、sessionStorage、localStorage,都適用,作些許調整便可哦,但願今天的分享能給您帶來些許成長,若是以爲不錯,記得關注下方公衆號哦,每週第一時間爲您推最新分享👇👇。git

專一於前端、測試領域的分享,歡迎關注咱們,寶劍鋒從磨礪出,梅花香自苦寒來,作有溫度的攻城獅!,公衆號:honeyBadger8

更多文章:

做者:蘇南 - 首席填坑官
連接: https://blog.csdn.net/weixin_...
交流: 912594095,公衆號: honeyBadger8
本文原創,著做權歸做者全部。商業轉載請聯繫 @IT·平頭哥聯盟得到受權,非商業轉載請註明原連接及出處。
相關文章
相關標籤/搜索