总结JavaScript三种数据存储方式之间的区别


Posted in Javascript onMay 03, 2016

sessionStorage 、localStorage 和 cookie 之间的共同点:
都是保存在浏览器端,且同源的。

sessionStorage 、localStorage 和 cookie 之间的区别:
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
Web Storage 的 api 接口使用更方便。

封装的localStorage的方法,可以控制存储数据的条数,以及时间

define(function (require) {
  var $ = require('jquery');
  var Cache = {};

  function support() {
    var _t = !(typeof window.localStorage === 'undefined');
    return _t;
  }


  $.extend(Cache, {
    config: {
      size: 5,
      // lifeTime: 86400 //一天的秒数
      lifeTime: 1*60
    },
    localStorage: window.localStorage,
    memQueue: (function () {
      if (support()) {
        var jsonStr = window.localStorage.getItem('LRUConfig');
        return jsonStr ? JSON.parse(jsonStr) : {
          keys: {},
          objs: []
        };
      } else {
        return {};
      }
    })(),

    get: function(appid, url) {
      if (true == support()) {
        var key = appid + ':' + url;
        //开始做LRU算法。
        this.LRU(key);
        //LRU算法结束。
        var isFresh = true;
        var nowTime = (new Date()).getTime() / 1000;
        if(key in this.memQueue.keys){
          var cacheTime = this.memQueue.keys[key].life / 1000;
          //如果过期时间超过 配置的lifeTime,
          //则清除掉当前缓存
          if(nowTime - cacheTime >= this.config.lifeTime){
            delete this.memQueue.keys[key];
            for (var i=0, len = this.memQueue.objs.length; i < len; i++) {
              var _o = this.memQueue.objs[i];
              if(_o.key == key){
                this.memQueue.objs.splice(i,1);
                break;
              }
            }
            isFresh = false;
          }
        }
        //如果isFresh为假,就是已过期,则返回null,否则从localStorage中取
        return (false == isFresh) ? null : this.localStorage[key];
      }
    },
    set: function(appid, url, value) {
      if (true == support()) {
        var key = appid + ':' + url;
        var lruKey = this.getLRU();
        //淘汰最近最少使用的这个。
        //另外起一个方法读取最符合淘汰的这个
        //前提是当前这个key,不在localStorage里面。
        if (lruKey) {
          this.localStorage.removeItem(lruKey);
        }
        //开始设置一下这个值
        //为了兼容性,用以下方法设置
        if (typeof this.memQueue.objs != 'undefined' &&
          this.memQueue.objs.length <= this.config.size) {
          this.localStorage.removeItem(key);

        } else {
          while (this.memQueue.objs.length >= this.config.size) {
            var lruKey = this.getLRU();
            //淘汰最近最少使用的这个。
            //另外起一个方法读取最符合淘汰的这个
            if (lruKey) {
              this.localStorage.removeItem(lruKey);
              delete this.memQueue.keys[lruKey];
              for (var i = 0; i < this.memQueue.objs.length; i++) {
                var _o = this.memQueue.objs[i];
                if(_o.key == lruKey){
                  this.memQueue.objs.splice(i,1);
                  break;
                }
              }
            }
          }
        }

        this.localStorage[key] = value;
        //当前的key,也必须lru一下
        this.LRU(key);
        //lru结束

        this.localStorage.setItem('LRUConfig', JSON.stringify(this.memQueue));
      }
    },
    /*
     * 近期最少使用算法
     */
    LRU: function(key) {
      var memQueue = this.memQueue;
      if (typeof memQueue.objs != 'undefined') {
        var _o = memQueue.objs;

        //开始计算那个要淘汰的key,
        //就是那个times最大的,如果times最大的有几个
        //则返回那个time最小的
        var isIn = false;
        for (var i = 0, len = _o.length; i < len; i++) {
          _o[i].times = (key == _o[i].key) ? 0 : _o[i].times + 1;
          _o[i].time = (key == _o[i].key) ? (new Date()).getTime() : _o[i].time;
          if(key == _o[i].key && false == isIn){
            isIn = true;
          }
        }
        // 如果
        if(false == isIn){
          var _to = {
            'key': key,
            'times': 0,
            'time': (new Date()).getTime(),
            'life': (new Date()).getTime()
          };
          this.memQueue.keys[key] = _to;
          this.memQueue.objs.push(_to);
        }
        _o.sort(function(f, s) {
          //按times降序排列。
          if (f.times < s.times) {
            return 1;
          } else if (f.times > s.times) {
            return -1;
          } else {
            //开始比较time
            //按time,时间升序排列
            if (f.time < s.time) {
              return -1;
            } else {
              return 1;
            }
          }
        });
      } else {
        this.memQueue.objs = [];
        this.memQueue.keys = {};
        var _to = {
          'key': key,
          'times': 0,
          'time': (new Date()).getTime(),
          'life': (new Date()).getTime()
        };
        this.memQueue.keys[key] = _to;
        this.memQueue.objs.push(_to);
        return null;
      }
    },
    /*
     * 读取需要淘汰的一项
     */
    getLRU: function() {
      var _o = this.memQueue.objs;
      if (_o) {
        return (_o.length >= this.config.size) ? _o.shift().key : null;
      }

      return null;

    }
  });


  return {
    'cache': Cache
  };
});

使用方法

var cache = require('cache');
// set 值
cache.Cache.set('ip', '你自己的一个url', value);

// get值
cache.Cache.get('ip')
Javascript 相关文章推荐
百度留言本js 大家可以参考下
Oct 13 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
Oct 11 Javascript
jquery 合并内容相同的单元格(示例代码)
Dec 13 Javascript
结合JQ1.9通过js正则判断各种浏览器版本的方法
Dec 30 Javascript
js中通过父级进行查找定位元素
Jun 15 Javascript
原生js和jQuery随意改变div属性style的名称和值
Oct 22 Javascript
jquery增加和删除元素的方法
Jan 14 Javascript
jQuery遍历DOM节点操作之filter()方法详解
Apr 14 Javascript
很酷的星级评分系统原生JS实现
Aug 25 Javascript
值得分享和收藏的xmlplus组件学习教程
May 05 Javascript
基于JavaScript实现微信抢红包功能
Jul 20 Javascript
从对象列表中获取一个对象的方法,依据关键字和值
Sep 20 Javascript
深入解析jQuery中Deferred的deferred.promise()方法
May 03 #Javascript
浅析函数声明和函数表达式——函数声明的声明提前
May 03 #Javascript
详解JavaScript异步编程中jQuery的promise对象的作用
May 03 #Javascript
jQuery的promise与deferred对象在异步回调中的作用
May 03 #Javascript
JavaScript的MVVM库Vue.js入门学习笔记
May 03 #Javascript
聊一聊JavaScript作用域和作用域链
May 03 #Javascript
小白谈谈对JS原型链的理解
May 03 #Javascript
You might like
关于手调机和数调机的选择
2021/03/02 无线电
php getsiteurl()函数
2009/09/05 PHP
PHP正则的Unknown Modifier错误解决方法
2010/03/02 PHP
PHP 可阅读随机字符串代码
2010/05/26 PHP
PHP中的string类型使用说明
2010/07/27 PHP
PHP函数之日期时间函数date()使用详解
2013/09/09 PHP
ThinkPHP框架设计及扩展详解
2014/11/25 PHP
php获取网站百度快照日期的方法
2015/07/29 PHP
php实现异步数据调用的方法
2015/12/24 PHP
Laravel手动分页实现方法详解
2016/10/09 PHP
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
2013/10/15 Javascript
javascript中打印当前的时间实现思路及代码
2013/12/18 Javascript
一个JavaScript防止表单重复提交的实例
2014/10/21 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
原生JS实现图片懒加载(lazyload)实例
2017/06/13 Javascript
详解angularjs获取元素以及angular.element()用法
2017/07/25 Javascript
微信小程序 swiper组件构建轮播图的实例
2017/09/20 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
详解javascript对数组和json数组的操作
2019/04/15 Javascript
JS实现的雪花飘落特效示例
2019/12/03 Javascript
[06:24]DOTA2 2015国际邀请赛中国区预选赛第二日TOP10
2015/05/27 DOTA
python线程池的实现实例
2013/11/18 Python
Python模拟登录验证码(代码简单)
2016/02/06 Python
Python中使用多进程来实现并行处理的方法小结
2017/08/09 Python
Python pyinotify日志监控系统处理日志的方法
2018/03/08 Python
python GUI库图形界面开发之PyQt5线程类QThread详细使用方法
2020/02/26 Python
Python 创建守护进程的示例
2020/09/29 Python
详解appium自动化测试工具(monitor、uiautomatorviewer)
2021/01/27 Python
七年级历史教学反思
2014/02/05 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
刑事撤诉申请书
2015/05/18 职场文书
自荐信大全
2019/03/21 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
从结婚开始的恋爱故事。小说《我的美好婚事》TV动画化决定
2022/04/07 日漫