V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
southSu
V2EX  ›  分享创造

如何给 localStorage 设置一个有效期?

  •  
  •   southSu ·
    meibin08 · 2018-11-07 08:11:58 +08:00 · 4293 次点击
    这是一个创建于 1991 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如何给 localStorage 设置一个有效期

    引言

    ​  这个话题其实在上次分享<小程序填坑记里讲过了>已经讲过(大佬可绕过哦~),但后来群里 /评论都有些同学,提到了一些疑问,问能否单独整理一篇更为详细的分享,讲解一下细节和完善提到的不足,如是有了下文👇。

    这里是@IT·平头哥联盟,我是首席填坑官苏南,用心分享 做有温度的攻城狮。 公 Z 号:honeyBadger8,群:912594095

    思考点

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

    • Cookie 从你设置的时候,就会给个时间,不设置默认会话结束就过期;
    • 淘宝购物 从你下单付款起,就会给这件货物设置一个收货期限时间,过了这个时间自动认为你收货(即订单结束);
    • 闹钟 你设置的提醒时间,其实也就是它的过期时间;
    • 再比如与您每天切身相关的产品需求,过完需求,你给出的上线时间,也就是这个需求的过期时间;
    • 再通俗点讲,您今年的生日过完到明年生日之间也是相当于设置了有效期时间;

    !> 以上种种,我们能得出一个结论任何一件事、一个行为动作,都有一个时间、一个节点,甚至我们可以黑localStorage,就是一个完善的 API,为什么不能给一个设置过期的机制,因为sessionStorageCookie并不能满足我们实际的需求。

    实现思路

    抱歉,黑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·平头哥联盟-首席填坑官∙苏南 分享
    	*/
    	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·平头哥联盟-首席填坑官∙苏南 分享
    	*/
    	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·平头哥联盟-首席填坑官∙苏南 分享
    		*/
    		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,都适用,做些许调整即可哦,希望今天的分享能给您带来些许成长,如果觉得不错,记得关注下方公众号哦,每周为您推最新分享👇👇。

    宝剑锋从磨砺出,梅花香自苦寒来,做有温度的攻城狮!,公众号:honeyBadger8

    作者:苏南 - 首席填坑官
    链接: https://blog.csdn.net/weixin_43254766/article/details/83618630
    交流群:912594095、公众号:honeyBadger8
    本文原创,著作权归作者所有。商业转载请联系@IT·平头哥联盟获得授权,非商业转载请注明原链接及出处。

    12 条回复    2018-11-07 19:10:35 +08:00
    southSu
        1
    southSu  
    OP
       2018-11-07 08:12:15 +08:00
    清风舞明月,幽梦落花间。
    一梦醒来,恍如隔世,
    两眉间,相思尽染。——我是苏南,周三早安,愿您安好!😃
    cctv1005s927
        2
    cctv1005s927  
       2018-11-07 08:22:15 +08:00
    平头哥??
    Showfom
        3
    Showfom  
       2018-11-07 08:29:16 +08:00
    看我打球,跟我去食堂,我又是平头,你喜欢我吧?
    @cctv1005s927

    https://i.loli.net/2018/11/07/5be231d7aa680.png
    MuscleOf2016
        4
    MuscleOf2016  
       2018-11-07 08:34:43 +08:00
    吓得我以为,江苏 苏南 苏北 内斗尼。哈哈。
    des
        5
    des  
       2018-11-07 08:35:47 +08:00 via Android
    平头哥??
    lancegin
        6
    lancegin  
       2018-11-07 08:49:51 +08:00 via iPhone
    美凌格
    farseeraliens
        7
    farseeraliens  
       2018-11-07 09:42:26 +08:00 via iPhone
    请问 set 后一直不 get 就没效果了吗?
    cctv1005s927
        8
    cctv1005s927  
       2018-11-07 13:56:06 +08:00
    southSu
        9
    southSu  
    OP
       2018-11-07 14:05:26 +08:00
    @cctv1005s927

    不那么好过的日子里,
    要学会每天给自己找一个开心的理由,
    哪怕只是阳光很暖,电量很满!——下午好,感谢支持,我们是几个朋友一起弄的个团队写点博客而已,不是马老师的平头哥,欢迎关注哦
    southSu
        10
    southSu  
    OP
       2018-11-07 14:07:23 +08:00
    @farseeraliens
    每一个人都应该用努力去惊艳时光,
    生活不会亏待任何一个努力的人!-——下午好,感谢支持,this.initRun();方法初始化会进行删除过期的数据,set 之后,肯定要 get 才能取到你要东西,localstorage 本身也是如此!
    southSu
        11
    southSu  
    OP
       2018-11-07 14:08:23 +08:00
    @MuscleOf2016

    最美好的生活方式
    奔跑在理想的路上,
    回头有一路的故事,
    低头有坚定的脚步,
    抬头有清晰的远方!——下午好,不是哦,只是一个名字而已
    Showfom
        12
    Showfom  
       2018-11-07 19:10:35 +08:00
    @cctv1005s927 平头哥的来历啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2755 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:46 · PVG 20:46 · LAX 05:46 · JFK 08:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.