如何给localStorage设置一个过期时间?

转载地址:https://segmentfault.com/a/1190000016892019   尊重原创

​  从我们接触前端起,第一个熟悉的存储相关的Cookie或者来分析我们生活中密切相关的淘宝、物流、闹钟等事物来说起吧,

  • Cookie从你设置的时候,就会给个时间,不设置默认会话结束就过期; 淘宝购物

  • 从你下单付款起,就会给这件货物设置一个收货期限时间,过了这个时间自动认为你收货(即订单结束); 闹钟

  • 你设置的提醒时间,其实也就是它的过期时间; 再比如与您每天切身相关的产品需求,过完需求,你给出的上线时间,也就是这个需求的过期时间;

  • 再通俗点讲,您今年的生日过完到明年生日之间也是相当于设置了有效期时间;

以上种种,我们能得出一个结论任何一件事、一个行为动作,都有一个时间、一个节点,甚至我们可以黑localStorage,就是一个完善的API,为什么不能给一个设置过期的机制,因为sessionStorage、Cookie并不能满足我们实际的需求。
实现思路
  抱歉,黑localStorage不完善,有点夸张了,综合上述的总结,问题就简单了,给localStorage一个过期时间,一切就都so easy ?到底是不是,来看看具体的实现吧:

简单回顾

//示例一:
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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值