总结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 相关文章推荐
Javascript String对象扩展HTML编码和解码的方法
Jun 02 Javascript
js 判断一个元素是否在页面中存在
Dec 27 Javascript
css样式标签和js语法属性区别
Nov 06 Javascript
jquery为页面增加快捷键示例
Jan 31 Javascript
教你在heroku云平台上部署Node.js应用
Jul 30 Javascript
node.js中的fs.unlink方法使用说明
Dec 15 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
Dec 16 Javascript
Vue.js实现拖放效果的实例
Sep 30 Javascript
TableSort.js表格排序插件使用方法详解
Feb 10 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
Feb 21 Javascript
angularjs之$timeout指令详解
Jun 13 Javascript
React如何使用axios请求数据并把数据渲染到组件
Aug 05 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
你应该知道PHP浮点数知识
2015/05/13 PHP
完美解决php 导出excle的.csv格式的数据时乱码问题
2017/02/18 PHP
jquery 插件开发备注
2010/08/27 Javascript
jQuery动态添加的元素绑定事件处理函数代码
2011/08/02 Javascript
单击复制文字兼容各浏览器的完美解决方案
2013/07/04 Javascript
onkeyup,onkeydown和onkeypress的区别介绍
2013/10/21 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
2014/06/24 Javascript
让angularjs支持浏览器自动填表
2014/11/10 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
js表单验证实例讲解
2016/03/31 Javascript
nodejs批量下载图片的实现方法
2017/05/19 NodeJs
Angularjs单选框相关的示例代码
2017/08/17 Javascript
vue下跨域设置的相关介绍
2017/08/26 Javascript
详解vue中axios请求的封装
2019/04/08 Javascript
JavaScript实现选项卡效果的分析及步骤
2019/04/16 Javascript
详解在vue-cli3.0中自定css、js和图片的打包路径
2019/08/26 Javascript
Vue2.0 $set()的正确使用详解
2020/07/28 Javascript
python在控制台输出进度条的方法
2015/06/20 Python
代码分析Python地图坐标转换
2018/02/08 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
python制作简单五子棋游戏
2019/06/18 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
python sklearn常用分类算法模型的调用
2019/10/16 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
Python如何重新加载模块
2020/07/29 Python
详解如何使用Pytest进行自动化测试
2021/01/14 Python
CSS3之2D与3D变换的实现方法
2019/01/28 HTML / CSS
html5基础标签(html5视频标签 html5新标签用法)
2013/12/30 HTML / CSS
Bergfreunde丹麦:登山装备网上零售商
2017/02/26 全球购物
贝嫂喜欢的婴儿品牌,个性化的婴儿礼物:My 1st Years
2017/11/19 全球购物
Myprotein意大利官网:欧洲第一运动营养品牌
2018/11/22 全球购物
美工的岗位职责
2013/11/14 职场文书
个人评价范文分享
2014/01/11 职场文书
作文批改评语大全
2014/04/23 职场文书
社会实践活动总结报告
2014/04/29 职场文书
my.ini优化mysql数据库性能的十个参数(推荐)
2021/05/26 MySQL