10访问者,解释器

访问者模式

  • 针对对象结构中的元素,定义在不改变对象前提下访问结构元素的新方法;

对象访问器例子

var Visitor = (function () {
  return {
    splice: function () {
      var args = Array.prototype.splice.call(arguments, 1);
      return Array.prototype.splice.apply(arguments[0], args);
    },
    push : function () {
      var len = arguments[0].length || 0;
      var args = this.splice(arguments, 1);
      arguments[0].length = len + arguments.length - 1;
      return Array.prototype.push.apply(arguments[0], args);
    },
    pop: function () {
      return Array.prototype.pop.apply(arguments[0]);
    }
  }
})();

var a = {};
Visitor.push(a, 1, 3, 4);
Visitor.push(a, 3, 4, 5);
Visitor.pop(a);
Visitor.splice(a, 1);

备忘录模式

  • 在不破坏对象封装性前提下,在对象之外捕获并保存该对象内部的状态以便日后使用或恢复到某个状态;

新闻页面缓存器例子

var Page = function () {
  var cache = {};
  return function (page, fn) {
    if(cache[page]) {
      showPage(page, cache[page]);
      fn && fn();
    } else {
      $.post('./data/getNewsData', {
        page: page
      }, function (res) {
        if(res.errNo === 0) {
          showPage(page, res.data);
          cache[page] = res.data;
          fn && fn();
        } else {
          ....
        }
      })
    }
  }
}
  • 缓存数据可以减轻重复性请求数据的压力;
  • 但数据量过大时需要考略缓存的优化或限制措施;

解释器模式

  • 对于一种语言,给出其文法表示形式,并定义一种解释器,通过使用这种解释器来解释语言中定义的句子;

统计元素路径例子

var Xpath = (function (){
  function getSublingName(node) {
    if(node.previousSibling) {
      var name = '', count = 1, 
        nodeName = node.nodeName,
        sibling = node.previousSibling;
      while(sibling) {
        if(sibling.nodeType == 1 && sibling.nodeType === node.nodeType && sibling.nodeName) {
          if(nodeName == sibling.nodeName)
          	name += ++count;
          else {
            count = 1;
            name += '|' + sibling.nodeName.toUpperCase();
          }
        }
        sibling = sibling.previousSibling;
      }
      return name;
    } else {
      return '';
    }
  }
  return function (node, wrap) {
    var path = [], wrap = wrap || document;
    if(node === wrap) {
      if(wrap.nodeType == 1)
        path.push(wrap.nodeName.toUpperCase());
      return path;
    }
    if(node.parentNode !== wrap)
      path = arguments.callee(node.parentNode, wrap);
    else {
      if(wrap.nodeType == 1)
      	path.push(wrap.nodeName.toUpperCase());
    }
    var sublingsNames = getSublingName(node);
    if(node.nodeType == 1)
      path.push(node.nodeName.toUpperCase() + sublingsNames)
    return path;
  }
})();

var path = Xpath(document.querySelector('span'));
console.log(path.join('>'));

委托模式

  • 多个对象接受处理同一请求,将请求委托给另一个对象统一处理;

委托给父元素,点击事件例子

  document.querySelector('ul').onclick = function (event) {
    var event = event || window.event;
    var tar = event.target || event.srcElement;
    if(tar.nodeName === 'LI')
      tar.style.background = 'grey';
  }
  • 解决内存泄漏问题;如果绑定给子元素,执行后子元素在DOM中消失,但绑定事件仍然存在;

委托数据处理

var Deal = {
  banner: function (data) {....},
  asider: function (data) {....}
  ....
};

$.get('./deal', function (res) {
//数据包分发
  for(var i in res) {
    Deal[i] && Deal[i](res[i])
  }
})
原文地址:https://www.cnblogs.com/jinkspeng/p/4893448.html