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

引言

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

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

思考点

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

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

以上种种,咱们能得出一个结论任何一件事、一个行为动做,都有一个时间、一个节点,甚至咱们能够黑localStorage,就是一个完善的API,为何不能给一个设置过时的机制,由于sessionStorageCookie并不能知足咱们实际的需求。git

实现思路

  抱歉,黑localStorage不完善,有点夸张了,综合上述的总结,问题就简单了,给localStorage一个过时时间,一切就都so easy ?究竟是不是,来看看具体的实现吧:github

简单回顾

//示例一:
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,都适用,作些许调整便可哦,但愿今天的分享能给您带来些许成长,若是以为不错,记得点个赞哦,顺便关注下方公Z号就更棒了,每周为您推最新分享👇👇。小程序

宝剑锋从磨砺出,梅花香自苦寒来,作有温度的攻城狮!,公众号:honeyBadger8,梅斌的专栏,首席填坑官∙苏南的专栏
用心分享,作有温度的攻城狮!

做者:苏南 - 首席填坑官
连接:blog.csdn.net/weixin_4325…
交流群:91259409五、公众好:honeyBadger8
本文原创,著做权归做者全部。商业转载请联系@IT·平头哥联盟得到受权,非商业转载请注明原连接及出处。数组

相关文章
相关标签/搜索