總結(jié)JavaScript三種數(shù)據(jù)存儲(chǔ)方式之間的區(qū)別

字號(hào):


    這篇文章主要介紹了JavaScript三種數(shù)據(jù)存儲(chǔ)方式之間的區(qū)別,指的分別是sessionStorage和localStorage以及cookie三種瀏覽器端的數(shù)據(jù)存儲(chǔ)方式,需要的朋友可以參考下
    sessionStorage 、localStorage 和 cookie 之間的共同點(diǎn):
    都是保存在瀏覽器端,且同源的。
    sessionStorage 、localStorage 和 cookie 之間的區(qū)別:
    cookie數(shù)據(jù)始終在同源的http請(qǐng)求中攜帶(即使不需要),即cookie在瀏覽器和服務(wù)器間來(lái)回傳遞。而sessionStorage和localStorage不會(huì)自動(dòng)把數(shù)據(jù)發(fā)給服務(wù)器,僅在本地保存。cookie數(shù)據(jù)還有路徑(path)的概念,可以限制cookie只屬于某個(gè)路徑下。
    存儲(chǔ)大小限制也不同,cookie數(shù)據(jù)不能超過(guò)4k,同時(shí)因?yàn)槊看蝖ttp請(qǐng)求都會(huì)攜帶cookie,所以cookie只適合保存很小的數(shù)據(jù),如會(huì)話標(biāo)識(shí)。sessionStorage和localStorage 雖然也有存儲(chǔ)大小的限制,但比cookie大得多,可以達(dá)到5M或更大。
    數(shù)據(jù)有效期不同,sessionStorage:僅在當(dāng)前瀏覽器窗口關(guān)閉前有效,自然也就不可能持久保持;localStorage:始終有效,窗口或?yàn)g覽器關(guān)閉也一直保存,因此用作持久數(shù)據(jù);cookie只在設(shè)置的cookie過(guò)期時(shí)間之前一直有效,即使窗口或?yàn)g覽器關(guān)閉。
    作用域不同,sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個(gè)頁(yè)面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
    Web Storage 支持事件通知機(jī)制,可以將數(shù)據(jù)更新的通知發(fā)送給監(jiān)聽(tīng)者。
    Web Storage 的 api 接口使用更方便。
    封裝的localStorage的方法,可以控制存儲(chǔ)數(shù)據(jù)的條數(shù),以及時(shí)間
    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 //一天的秒數(shù)
          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;
            //開(kāi)始做LRU算法。
            this.LRU(key);
            //LRU算法結(jié)束。
            var isFresh = true;
            var nowTime = (new Date()).getTime() / 1000;
            if(key in this.memQueue.keys){
              var cacheTime = this.memQueue.keys[key].life / 1000;
              //如果過(guò)期時(shí)間超過(guò) 配置的lifeTime,
              //則清除掉當(dāng)前緩存
              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為假,就是已過(guò)期,則返回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();
            //淘汰最近最少使用的這個(gè)。
            //另外起一個(gè)方法讀取最符合淘汰的這個(gè)
            //前提是當(dāng)前這個(gè)key,不在localStorage里面。
            if (lruKey) {
              this.localStorage.removeItem(lruKey);
            }
            //開(kāi)始設(shè)置一下這個(gè)值
            //為了兼容性,用以下方法設(shè)置
            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();
                //淘汰最近最少使用的這個(gè)。
                //另外起一個(gè)方法讀取最符合淘汰的這個(gè)
                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;
            //當(dāng)前的key,也必須lru一下
            this.LRU(key);
            //lru結(jié)束
            this.localStorage.setItem('LRUConfig', JSON.stringify(this.memQueue));
          }
        },
        /*
         * 近期最少使用算法
         */
        LRU: function(key) {
          var memQueue = this.memQueue;
          if (typeof memQueue.objs != 'undefined') {
            var _o = memQueue.objs;
            //開(kāi)始計(jì)算那個(gè)要淘汰的key,
            //就是那個(gè)times最大的,如果times最大的有幾個(gè)
            //則返回那個(gè)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 {
                //開(kāi)始比較time
                //按time,時(shí)間升序排列
                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;
          }
        },
        /*
         * 讀取需要淘汰的一項(xiàng)
         */
        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', '你自己的一個(gè)url', value);
    // get值
    cache.Cache.get('ip')