问题由来:网上说 localStorage 和 sessionStorage 的存储大小是 5M,那么这是一个精确数字还是一个估算数字?
测试下:
1 function getSize(storage) {
2 const _storage = window[storage];
3 let pieces = [20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0].map(
4 (bits) => 2 ** bits
5 ),
6 size = 0;
7 function trySize() {
8 if (pieces.length) {
9 const piece = pieces.shift();
10 try {
11 while (true) {
12 size += piece;
13 _storage.setItem(`${storage}:test`, "1".repeat(size));
14 }
15 } catch (err) {
16 size -= piece;
17 trySize();
18 }
19 }
20 }
21
22 _storage.clear();
23
24 trySize();
25
26 _storage.clear();
27
28 return size;
29 }
30
31 console.log(getSize("localStorage")); // 5242863
32 console.log(getSize("sessionStorage")); // 5242861
分析:这个结果一看就知道不是 5 * 2 ** 20,肯定不是 5M,直接在浏览器 F12 测试下这个结果,
可以看到,增加一个字节也能存储,为什么会这样呢,我看了好几次代码都没找到问题所在。
然后我就继续在 F12 里测试了很多遍,终于发现问题了,
从上面几条测试记录来看,'aaa' 的存储大小为 5242877,'aaaa' 的存储大小为 5242876,刚好差一个字节,而 'aaa' 和 'aaaa' 也刚好差一个字节,
这是不是说 localStorage 的存储大小是指 key 和 value,而不是单独的 value,
然后我们把 key 和 value 的字节数相加,
终于发现了,key 和 value 是作为一个整体存储的,这个数字刚好是 5 * 2 ** 20,
结果:由此可见,localStorage 的存储大小是刚好 5M,
继续测试下 sessionStorage 也是这样的,
上面代码的 return 需要改下,
return size + `${storage}:test`.length;
再次调用这个方法,
终于对上了,/(ㄒoㄒ)/~~