localStorage
和 sessionStorage
是 html5
新增的用来存储数据的对象,他们让咱们能够以键值对的形式存储信息。html
storage
?咱们已经有了 session
能够帮助咱们存储信息,为什么还须要 storage
呢?前端
cookie
长度大概只能在 4kb
左右,而 storage
大概能达到 5M
,这意味着能够存储更多的信息cookie
能够被后端更改,在每次进行网络请求的时候都会被发送给服务器,而 storage
不会,这意味着这个存储是彻底受控于前端(JavaScript)的。storage
一共有两种html5
localStorage
chrome
这个存储对象的存储和 origin
有关,即只要是同域名同协议同端口,存储是共享的。尽管关机了,或是关掉浏览器了,只要打开同源网站,存储的数据会依然存在,数据不会过时消失。后端
sessionStorage
api
这个存储对象的存储是暂时的,只保持在当前会话中,简单来讲就是和浏览器的一个 tab
有关,只要 tab
关掉了再打开数据就没了,可是在当前界面刷新的话,数据就还在(这个时候认为是一个 tab
)。数组
两个 storage
的 api
很类似,下面以 localStorage
为例浏览器
api
localStorage.setItem("name", "huro"); // 设置键值对
能够在 chrome
浏览器的控制台进行观察,这里已经设置上去了。下面也能够作相应的测试。服务器
localStorage.getItem("name"); // huro localStorage.removeItem("name"); // 删除某个键 localStorage.clear(); // 删除全部键值对 localStorage.key(0); // 得到索引为 0 的key localStorage.length; // 得到 `localStroage` 的键的个数
以上是 storage
的 api
cookie
惟一须要注意的是 key(index)
这个 api
和 key
被设置的前后是没有关系的。
也能够用类对象的方法操做
localStorage.name = "huro"; console.log(localStorage.name); // huro delete localStorage.name; // 删除键
可是上面的作法不推荐,若是用的是某些特殊的 key
例如 length
就会报错,由于原先 localStorage.length
表示得到键值对长度,理应是不能修改的。
localStorage["length"] = 4; // 修改无效
所以不推荐用这个作法修改 storage
因为 storage
并无 Symbol.iterator
属性,这意味着 storage
不能用 for of
循环遍历。如下有三种遍历方式。
假设咱们只有一个键值对 name: huro
for in
循环for (let key in localStorage) { console.log(key); }
上述的写法是错误的,由于 for in
循环会遍历原型链上的属性和方法,所以须要稍做改善。
for (let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; } console.log(key); }
这个时候就能正确的只打印出键 name
for
循环for(let i = 0; i < localStorage.length; i+= 1) { let key = localStorage.key(i); console.log(key); }
这个时候能正确的只打印出键 name
Object.keys()
这个方法会得到某个对象自身的 key
,而不会管原型链上的
const keys = Object.keys(localStorage); for(let key of keys) { alert(key); }
并且得到的 key
是数组,具备 iterator
所以能够用 for of
遍历
这个时候能正确的只打印出键 name
string
storage
被设计出来比较不足的地方是,键和值都只能是 string
类型的,若是不是的话,会自动转换成 string
。
因为是隐式转换,初学者每每不知道,这意味着可能带来一些 bug
localStorage.user = { name: "huro" }; console.log(localStorage.user); // [object Object]
上述代码在存储 user
的时候,被自动调用 toString
方法,转化为了 [object Object]
storage
事件storage
事件返回一个对象,里面包含几个参数
key
改变的键oldValue
=> 旧值 || null
newValue
=> 新值 || null
url
触发这个事件的 url
地址storageArea
要么是 localStorage
要么是 sessionStorage
取决与是更改哪一个storage
的// 1.html window.addEventListener("storage", (state) => { console.log(state.key, state.value, state.url); // name huro ./2.html(实际 url 是绝对路径) }) // 2.html localStorage.setItem("name", "huro");
还记得咱们以前说过, localStorage
只要是同源均可以分享吗,这意味若是咱们打开了两个窗口,只要他们是同源的,咱们能够用上述的监听事件,监听另外一个端口修改 storage
,也就是能够实现不一样的窗口之间的数据共享。
注意: 经测试,chrome
edge
等现代浏览器不会触发自身文件或同文件的 storage
事件,即必须是两个不一样的 html
才会互相触发。
例如 test1.html
和 test2.html
都设置了 storage
监听事件,且同源。
则 test1.html
的 storage
的 api
事件会触发 test2.html
的,可是不能触发自己的 storage
监听事件。
另外这里的 api
事件也有限制,通过笔者测试,彷佛只有
setItem
getItem
removeItem
有效果,而 clear
事件是没有效果的。
上面全程用 localStorage
演示,
sessionStorage
也是相似的,读者有兴趣能够自行码一下代码。
storage
是很好的一个 html5
特性,让咱们方便快捷的存储数据,美中不足的是只能存储字符型数据,不过也很容易解决这个问题。同时利用监听事件,也能够实现不一样窗口之间的广播机制。是很是实用的一个特性。