前言
localStorage是什么?
localStorage
是一个用来做本地持久化存储的Web Api。localStorage
以键值对的形式存储数据。它的常用方法如下:
// 设置
localStorage.setItem(key, val)
// 获取
const val = localStorage.getItem(key)
// 移除
localStorage.removeItem(key)
// 清空
localStorage.clear()
具体有哪些作用在这里就不过多介绍。
封装localStorage
localStorage
的 Api 都已经比较简洁实用了, 那还有什么好封装的呢?我的想法主要是为了解决以下几点:
- 设置/获取时可能出现的意外错误
- 设置/获取的value值都是字符串,不方便直接使用。
- 没有像
cookie
一样的过期时间限制
好了,不多说,直接撸代码:
const ls = window.localStorage
// 设置
const setItem = (key, val, expired) => {
// expired参数为毫秒数
try {
const data = {
[key]: val,
}
if (expired) {
data[`__${key}__expired`] = Date.now() + expired
}
ls.setItem(key, JSON.stringify(data))
} catch (e) {
console.log('setItem error', e)
}
}
// 获取
const getItem = key => {
try {
const data = JSON.parse(ls.getItem(key))
if (!data) return
if (data.hasOwnProperty(`__${key}__expired`)) {
if (data[`__${key}__expired`] >= Date.now()) {
return data[key]
}
removeItem(key)
return
}
return data[key]
} catch (e) {
console.log('getItem error', e)
}
}
// 移除
const removeItem = key => {
ls.removeItem(key)
}
// 清空
const clear = () => {
ls.clear()
}
export default { setItem, getItem, removeItem, clear }
代码不多解释,没有什么复杂的逻辑
你可能不知道的localStorage
我们都知道localStorage
是HTML5 Web存储的一部分,HTML5 Web 存储是以键/值对的形式存储的,那键/值对的集合不就是对象Object
吗?localStorage
和Object
有什么关系呢??
由上图我们知道原来localStorage
继承Storage
, 而Storage
又是继承Object
。它们的原型链关系是:
localStorage.__proto__ === Storage.prototype
Storage.prototype.__proto__ === Object.prototype
- 既然继承于
Object
,那肯定可以使用一些对象的方法
// 可以使用hasOwnProperty判断键是否被储存
localStorage.hasOwnProperty('name') === true
localStorage.hasOwnProperty('name1') === false
- 可以使用
Object.keys
得到键的可遍历集合
Object.keys(localStorage) // ["b", "name", "age", "a"]
localStorage
存在length
属性,表示存储键/值的数量
// 数量
localStorage.length // 2
- 可以使用点语法.或者中括号[]的形式访问
localStorage
中存储的值吗?
// 设置
localStorage.name = 'zhangsan'
localStorage['age'] = 19
// 获取
localStorage.name // 'zhangsan'
localStorage.age // '19'
那既然可以直接使用点语法.或者中括号[]的形式,为什么还需要setItem、getItem
呢?继续探索。
const str = 'string'
const obj = { obj: 'obj'}
const s = Symbol('s')
localStorage.setItem(str,'string1') // string => 'string1'
localStorage[str] = 'string2' // string => 'string2'
// 相同键名出现覆盖
localStorage.setItem(obj,'obj1') // [object Object] => 'obj1'
localStorage[obj] = 'obj2' // [object Object] => 'obj2'
localStorage.setItem(obj,obj) // [object Object] => '[object Object]'
localStorage[obj] = obj // [object Object] => '[object Object]'
// 相同键名出现覆盖
localStorage.setItem(s,'symbol') // TypeError: Cannot convert a Symbol value to a string
localStorage[s] = 'symbol' // Symbol(s) => 'symbol'
这里我们知道setItem(key,val)方法中的key、val必须为字符串或者可以被转换成字符串的其他类型。
当key为symbol类型时,使用setItem()设置失败,但是使用中括号[]设置时成功了。
那到底成功了吗?
localStorage.getItem(s) // TypeError: Cannot convert a Symbol value to a string
// 这里的错误应该还是 s 不能被转换成字符串的原因。
localStorage[s] // "symbol"
// why?localStorage的键不是应该只能为字符串类型吗?
陷入疑惑中...
我们尝试查看一下localStorage,如下图:
从打印结果来看,Symbol(s)键存在于localStorage对象中,但是length属性却没有因为增加了Symbol(s)键而改变。
再查看一下浏览器的Application:
为什么没有Symbol(s)键???
脑子里突然有一个想法,刷新一次浏览器看看。
哇哇哇。。。
我似乎明白了
总结
对象的键可以为Symbol类型,localStorage
也是一个对象。
因此可以使用中括号的方式给localStorage
添加Symbol类型的键。
但是localStorage
存在的意义是什么?持久化储存
!Symbol类型的键却做不到持久化,可能就是官方推荐使用setItem、getItem
接口的原因吧!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!