localStorage 封装

2,586 阅读2分钟

(1)初步封装,设置、获取、删除、清空 以及 获取总共存储的个数。

image.png

(2)问题:如果别人也存储 相同的key { 'a':2 },那么会把已经储存的 {'a':1} 覆盖掉。

=> 解决思路:加上特殊符号,比如下划线 ' _ ' 。

image.png

(3) 但这个 加上特殊符号,比如下划线 ' _ ' 是写死的,用户想要自定义的特殊符号

=> 解决思路:特殊符号可传,可不传(不传默认加下划线 '_')。

image.png

(4)问题:点击清空按钮,所有的存储全部被清空。

=> 解决思路:是谁点击清空,就只清空它自己的。例如 gg1 点击清空,就只清空 属于 gg1 的。

Gg.prototype.clear = function(){
    // localStorage.clear()  // -  -key
    Object.keys(localStorage).forEach(item => {
        if(item.startsWith(this.name)){
            localStorage.removeItem(item)
        }
    })
}

(5)设置时间,把时间同时也存储起来。

穿插一个tip:

对象转 JSON 字符串:如果是 undefined 或者 函数,参数会被丢失;如果是 NaN ,就会被转换 null 。

当没有传入参数 time 时,会被自动去掉time,因为 time 在JSON.stringify时,time如果是 undefined就会被丢失

image.png

(6)js的时间是毫秒,进行时间转换存储。

Gg.prototype.setItem = function(key, value, time){
    const _key = this.name + key
    const _value = {value}
    time && (_value.time = time *1000 + new Date().getTime())
    localStorage.setItem( _key,JSON.stringify(_value))
}

image.png

(7)已经存储了时间,就需要进行时间比较,当时间过期时,则删除这一条存储的数据。如果数据存在就返回该数据;如果数据不存在则返回 null 。

Gg.prototype.getItem = function(key){
    const _key = this.name + key 
    if (localStorage.getItem(_key)) {
        const time = JSON.parse(localStorage.getItem(_key)).time
        if (new Date().getTime() > time) {
            this.removeItem(key)
            return null
        }
        return JSON.parse(localStorage.getItem(_key)).value
    } else {
        return null
    }
}

(8)添加一个功能:判断这个数据存不存在,存在就返回 true;如果数据不存在则返回 false 。

逻辑和第7步是同理的。

Gg.prototype.hasItem = function(key){
    const _key = this.name + key
    if (localStorage.getItem(_key)) {
        const time = JSON.parse(localStorage.getItem(_key)).time
        if (new Date().getTime() > time) {
            this.removeItem(key)
            return false
        }
        return true
    } else {
        return false
    }
}

(9) 简化第7步代码。

Gg.prototype.getItem = function(key) {
    if(this.hasItem(key)) {
        return JSON.parse(localStorage.getItem( this.name + key)).value
    }
    return null
}

(10) 最后这里出现一个问题:设置的时间已经过期了,localStorage不会自动删除,即使刷新该数据仍旧存在,除非触发 getItem 。

=> 解决思路:执行一个初始函数init,以便 '自动' 获取最新的数据。

function Gg(name='_') {
    this.name = name
    this.init()
}
Gg.prototype.init = function() {
    Object.keys(localStorage).forEach(item => {
        if(item.startsWith(this.name)) {
            this.hasItem(item.replace(this.name, ''))
        }
    })
}

在文章结尾附上完整源码。

function Gg(name='_') {
    this.name = name
    this.init()
}
Gg.prototype.init = function() {
    Object.keys(localStorage).forEach(item => {
        if(item.startsWith(this.name)) {
            this.hasItem(item.replace(this.name, ''))
        }
    })
}
Gg.prototype.setItem = function(key,value,time) {
    if(value === undefined) value = null
    const _key = this.name + key
    const _value = {value}
    time && (_value.time = time *1000 + new Date().getTime())
    localStorage.setItem( _key,JSON.stringify(_value))
}
Gg.prototype.getItem = function(key) {
    if(this.hasItem(key)) {
        return JSON.parse(localStorage.getItem( this.name + key)).value
    }
    return null
}
Gg.prototype.removeItem = function(key) {
    localStorage.removeItem( this.name + key)
}
Gg.prototype.clear = function() {
    Object.keys(localStorage).forEach(item => {
        if(item.startsWith(this.name)) {
            localStorage.removeItem(item)
        }
    })
}
Gg.prototype.lenght = function() {
    return Object.keys(localStorage).length
}

Gg.prototype.hasItem = function(key) {
    const _key = this.name + key
    if(localStorage.getItem(_key)) {
        const _time = JSON.parse(localStorage.getItem(_key)).time
        if(new Date().getTime() > _time) {
            localStorage.removeItem(_key)
            return false 
        }
        return true
    } else {
        return false
    }
}

export {Gg}