访问者模式

概念介绍

访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法

解决低版本IE兼容性

我们来看下面这段代码,这段代码,我们封装了一个绑定事件的方法,接着我们调用这个方法,通过点击页面上的元素,改变元素的样式。

var bindEvent=function(dom,type,fn){
if(dom.addEventListener){
dom.addEventListener(type,fn,false);
}else if(dom.attachEvent){
dom.attachEvent('on'+type,fn);
}else{
dom['on'+type]=fn;
}
}
var test=document.getElementById('test');
bindEvent(test,'click',function(){
this.style.backgroundColor='red';
});

我们分别在谷歌和IE以及低版本的IE浏览器下看一看

我们发现在谷歌和高版本IE下我们的效果正常,到了IE8却提示this.style为空或不为对象,这是为什么呢?

现在我们调整一下代码,我们把绑定样式的代码去掉增加下面这段代码,再执行一下

alert(this===window);



我们发现在低版本的IE下返回的true(在IE7,IE8下不知道为什么alert没反应,我暂时还没找到原因,如果有知道的请告知,万分感谢。)

这样就解释了为什么我们之前的代码在低版本的IE下会抛异常,因为我们的this指向的是window而不是元素本身,所以我们如果想要获取事件对象,需要通过window.e

这个时候我们就可以通过访问者模式来解决事件回调函数中对该元素的访问问题。

function bindIEEvent(dom,type,fn){
dom.attachEvent('on'+type,function(e){
fn.call(dom,e);
});
};

访问者模式的实现核心其实就是调用了一次call方法,我们知道call和apply的作用就是更改函数执行时的作用域,这正是访问者模式的精髓所在

我们再来试试

bindIEEvent(test,'click',function(e){
this.style.backgroundColor='red';
});

我们看到现在在低版本的IE下就没问题了

注意!这个方法在谷歌和IE8以上版本会抛对象不支持attachEvent属性或方法异常

创建对象访问器

我们还可以通过访问者模式创建一个对象访问器,像操作数组那样处理一个对象,我们来看看具体实现

//创建访问器
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=new Object();
console.log(a.length);
Visitor.push(a,1,2,3,4);
console.log(a.length);
Visitor.push(a,4,5,6);
console.log(a);
console.log(a.length);
Visitor.pop(a);
console.log(a);
console.log(a.length);
Visitor.splice(a,2);
console.log(a);

总结

访问者模式解决数据与数据的操作方法之间的耦合,将数据的操作方法独立于数据,使其可以自由化演变。因此访问者更适合于那些数据稳定,但是数据的操作方法易便的环境下。因此当操作环境改变时,可以自由修改操作方法以适应操作环境,而不用修改原数据,实现操作方法的拓展。同时对于同一个数据它可以被多个访问对象所访问,这极大增加了操作数据的灵活性。

也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~

好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。

欢迎转载,转载请注明作者,原文出处。

再起航,我的学习笔记之JavaScript设计模式22(访问者模式)的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  2. 再起航,我的学习笔记之JavaScript设计模式09(原型模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

  3. 再起航,我的学习笔记之JavaScript设计模式11(外观模式)

    经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习. 结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何 ...

  4. 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)

    桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...

  5. 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)

    模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...

  6. 再起航,我的学习笔记之JavaScript设计模式20(策略模式)

    策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...

  7. 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)

    备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...

  8. 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)

    迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...

  9. 再起航,我的学习笔记之JavaScript设计模式26(解释器模式)

    解释器模式 概念介绍 解释器模式(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 获取元素在页面中的路径 我们都知道获取一个 ...

随机推荐

  1. TCP和UDP的区别(Socket)

    TCP和UDP区别 TCP和UDP编程区别 TCP编程的服务器端一般步骤是:  1.创建一个socket,用函数socket():  2.设置socket属性,用函数setsockopt(); * 可 ...

  2. MSPointerEvent属性

    MSPointerEvent属性 属性 描述 hwTimestamp 创建事件的时间(ms) isPrimary 标识该指针是不是主指针 pointerId 指针的唯一ID(类似于触摸事件的标识符) ...

  3. apache-DOS

    对DSO的理解还不是特别深刻,所以把自己查来的资料整理一下并想就此作一个总结.暂时先把资料堆到blog里面了,有时间再整理总结.   一.以下源于<Apache HTTP Server Vers ...

  4. mysql服务器主从数据库同步配置(转)

    <a href=""></a> <p>首先需要在同一个局域网内的两台机器(当然也可以用一台机器虚拟两台机器出来),都安装上mysql服务.< ...

  5. WebClient 调用api

    使用: /// <summary> /// 获取用户信息 /// </summary> /// <param name="code"></ ...

  6. 【Centos 7】使用screen恢复终端连接

    操作系统:centos7.1 (在ubuntu上测试过,不支持 screen) 主机:虚拟云主机 问题出现:在使用打包式在线安装phpstudy时,由于安装过程非常漫长,http报文过一段时间没有回送 ...

  7. 【Js应用实例】javascript管理cookie

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Java设计模式 (转)

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. java --jfree报表

    ---恢复内容开始--- 1.使用的报表工具: jfree报表 2.下载网址: http://www.jfree.org/ 下载之后先解压:如下图 下载后:需要的jar包!如下图: 打开:找到以下的两 ...

  10. GUI与UI的区别

    GUI 图形用户界面(**Graphical User Interface**,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面. 与早期计算机使用的命令行界面相比,图形界面对 ...