总结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 相关文章推荐
jquery 问答知识整理
Feb 11 Javascript
javascript Array数组对象的扩展函数代码
May 22 Javascript
用jquery等比例控制图片宽高的具体实现
Jan 28 Javascript
jquery自定义滚动条插件示例分享
Feb 21 Javascript
判断浏览器的内核及版本号方法汇总
Jan 05 Javascript
jquery使用正则表达式验证email地址的方法
Jan 22 Javascript
教你使用javascript简单写一个页面模板引擎
May 05 Javascript
详解JavaScript中的4种类型识别方法
Sep 14 Javascript
React Native悬浮按钮组件的示例代码
Apr 05 Javascript
微信小程序定位当前城市的方法
Jul 19 Javascript
JavaScript实现简单轮播图效果
Dec 01 Javascript
JS实现横向轮播图(中级版)
Jan 18 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
删除及到期域名的查看(抢域名必备哦)
2008/05/14 PHP
解析CodeIgniter自定义配置文件
2013/06/18 PHP
php 函数使用可变数量的参数方法
2017/05/02 PHP
用prototype实现的简单小巧的多级联动菜单
2007/03/24 Javascript
DOM下的节点属性和操作小结
2009/05/14 Javascript
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
jq实现酷炫的鼠标经过图片翻滚效果
2014/03/12 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
2014/05/06 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
常见的jQuery选择器汇总
2014/11/24 Javascript
nodejs实现的一个简单聊天室功能分享
2014/12/06 NodeJs
JavaScript String 对象常用方法详解
2016/05/13 Javascript
简单实现Vue的observer和watcher
2016/12/21 Javascript
基于Particles.js制作超炫粒子动态背景效果(仿知乎)
2017/09/13 Javascript
JS实现中英文混合文字溢出友好截取功能
2018/08/06 Javascript
npm 常用命令详解(小结)
2019/01/17 Javascript
vue实现搜索过滤效果
2019/05/28 Javascript
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
[15:28]DOTA2 HEROS教学视频教你分分钟做大人-剧毒术士
2014/06/13 DOTA
结合Python的SimpleHTTPServer源码来解析socket通信
2016/06/27 Python
深入解析Python中的上下文管理器
2016/06/28 Python
对Python使用mfcc的两种方式详解
2019/01/09 Python
python 默认参数相关知识详解
2019/09/18 Python
使用python去除图片白色像素的实例
2019/12/12 Python
python实现tail -f 功能
2020/01/17 Python
python+opencv3生成一个自定义纯色图教程
2020/02/19 Python
pycharm设置默认的UTF-8编码模式的方法详解
2020/06/01 Python
Matplotlib 折线图plot()所有用法详解
2020/07/28 Python
网络艺术零售业的先驱者:artrepublic
2017/09/26 全球购物
如何配置、使用和清除Smarty缓存
2015/12/23 面试题
专科毕业生学习生活的自我评价
2013/10/26 职场文书
公司会议策划方案
2014/05/17 职场文书
医院财务人员岗位职责
2015/04/14 职场文书
财产分割协议书
2016/03/22 职场文书
MySQL七大JOIN的具体使用
2022/02/28 MySQL
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android