上篇文章([0]-JavaScript中的localStorage和sessionStorage)中说到了Storage可以作为App的缓存,今天来和大家聊聊我在使用Array作为缓存载体的那些坑,关于数组的使用相信大家都有所了解,在此就不再赘述了。
- 目录
字符串作为数组索引
Array Like
- 字符串作为数组索引
在开发中使用Array做为缓存的载体时,为了方便查询和写入会使用字符串作为数组的索引:
1 var person = { 2 name: "Tom", 3 age: 29, 4 imaccount: "[email protected]" 5 }; 6 7 var cache = JSON.parse(localStorage.getItem(‘cache‘)); 8 if (cache == undefined) { 9 cache = []; 10 } 11 cache[person.imaccount] = person;
在业务场景下,用户的imaccount属性是唯一的,一个imaccount对应一个用户,这样的话可以使用一个Array作为缓存并且放入localStorage。
我们将刚才的数组进行序列化。(此处仅作示意,真正的缓存应更加完善、从localStorage序列化/反序列化应封装成工具方法)
1 localStorage.setItem(‘cache‘, JSON.stringify(cache));
在序列化之后查看Resources选项卡发现cache对应的值是 "[]" 一个空的数组,但是我们在数组中通过 cache[‘[email protected]‘] 获取添加到缓存的对象发现可以获取到,但是数组的 length 为0。这是因为在数组中使用字符串作为索引的项,不会占用长度,在toString时不会被打印。当时就是因为忽略了这一点导致刚开始开发时缓存就像没有一样,依然会每次请求服务器,到后来才逐渐发现这个坑。
如何避免这个问题呢?这就引出了我们今天要讨论的第二个话题Array Like(伪数组)。
- Array Like
Array Like即伪数组,拥有 length 属性和可以通过 [index] 的形式访问元素。函数执行时的 arguments 隐式对象就是一个Array Like。
我们发现arguments对象中存储了实参列表,还有 callee 和 length 属性。
callee 属性指向的是当前执行的函数本身,我们可以通过 arguments.callee() 调用当前执行的函数从而实现匿名函数的递归;说到 callee 就顺便说说 funcName.caller ,它指向了调用该函数的函数。
但arguments并不是Array的实例 arguments instanceof Array 返回的结果是 false ,如何让arguments变成真正的数组呢?
通过[]生成一个新数组,再通过call方法调用数组的slice方法将arguments转换成真正的数组就可以做数组相关的操作了。