总结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 相关文章推荐
IE6中链接A的href为javascript协议时不在当前页面跳转
Jun 05 Javascript
JS实现控制表格单元格垂直对齐的方法
Mar 30 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
Jul 27 Javascript
纯javascript实现分页(两种方法)
Aug 26 Javascript
jquery实现列表上下移动功能
Feb 25 Javascript
在AngularJS框架中处理数据建模的方式解析
Mar 05 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
Jul 13 Javascript
浅谈angular4生命周期钩子
Sep 05 Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 Javascript
Bootstrap Table中的多选框删除功能
Jul 15 Javascript
JS实现倒序输出的几种常用方法示例
Apr 13 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
Oct 27 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
超级简单的发送邮件程序
2006/10/09 PHP
php htmlentities和htmlspecialchars 的区别
2008/08/18 PHP
php中用date函数获取当前时间有误的解决办法
2013/08/02 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
基于jQuery的实现简单的分页控件
2010/10/10 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
js opener的使用详解
2014/01/11 Javascript
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
React数据传递之组件内部通信的方法
2017/12/31 Javascript
js判断文件类型大小并给出提示的实现方法
2018/01/03 Javascript
详解Angular系列之变化检测(Change Detection)
2018/02/26 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
vue + typescript + 极验登录验证的实现方法
2019/06/27 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
微信小程序调用wx.getImageInfo遇到的坑解决
2020/05/31 Javascript
JS操作JSON常用方法(10w阅读)
2020/12/06 Javascript
代码讲解Python对Windows服务进行监控
2018/02/11 Python
pandas实现选取特定索引的行
2018/04/20 Python
Python操作MySQL数据库的方法
2018/06/20 Python
python实现简单多人聊天室
2018/12/11 Python
python:接口间数据传递与调用方法
2018/12/17 Python
Python 虚拟空间的使用代码详解
2019/06/10 Python
Python IDE环境之 新版Pycharm安装详细教程
2020/03/05 Python
Python中的Cookie模块如何使用
2020/06/04 Python
keras使用Sequence类调用大规模数据集进行训练的实现
2020/06/22 Python
美国香薰蜡烛品牌:PADDYWAX
2018/10/06 全球购物
英超联赛的首选足球:Mitre足球
2019/05/06 全球购物
美国乒乓球设备、配件和服装品牌:Killerspin
2020/06/07 全球购物
给海归自荐信的建议
2013/12/13 职场文书
小学英语教学反思案例
2014/02/04 职场文书
幼儿园的门卫岗位职责
2014/04/10 职场文书
国旗下讲话演讲稿
2014/05/08 职场文书
邀请函的格式
2015/01/30 职场文书
六一文艺汇演主持词
2015/06/30 职场文书
Java中try catch处理异常示例
2021/12/06 Java/Android
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python