`

事件设计模式

阅读更多
1. 事件设计概述

    事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onclick事件,selcet有onchange事件。对于我们自己设计的类,是否也可以有事件机制呢?答案是肯定的。我们可以通过事件机制,将类设计为独立的模块,从而使其可以通过事件与外通信,提高程序的开发效率。

2. 不带参数的事件设计模式

    最简单的一种模式是将一个类的方法成员定义为事件,可以借助JavaScript的基本语法来实现,通常是一个空的方法。例如:
<script language="javascript" type="text/javascript" >   
  
function User(){   
}   
User.prototype={   
    show:function(){   
        this.onShow();//触发onShow事件   
    },   
    onShow:function(){}//定义事件接口   
}   
var obj = new User();   
//创建obj的onShow事件处理程序   
obj.onShow = function(){   
    alert("事件触发了");   
}   
//调用obj的show方法   
obj.show();   
</script>  

obj.onShow 方法在类的外部被定义,在类的内部方法 show() 中被调用,这就实现了事件机制。

    此设计模式应用起来简单,但有其有以下缺点:

不能够给事件处理程序传递参数,原因是我们是在 show() 这个内部方法中调用事件处理程序的,无法知道外部的参数。
每个事件接口只能绑定一个事件处理程序,而内部方法则可以使用 attachEvent 或 addEventListener 方法绑定多个处理程序。
3. 给事件处理程序传递参数

    给事件处理程序传递参数不仅是自定义事件中存在的问题,也是系统内部对象的事件机制中存在的问题,因为事件机制仅传递一个函数名称,不带有任何参数信息,所以无法传递参数进去。例如:
<script language="javascript" type="text/javascript" >   
function User(){   
}   
User.prototype={   
    show:function(){   
        this.onShow();//触发onShow事件   
    },   
    onShow:function(){}//定义事件接口   
}   
var obj = new User();   
//创建obj的onshow事件处理程序   
function objOnShow(userName){   
    alert("hello,"+userName);   
}   
//定义username变量   
var userName = "plkong";   
//绑定obj的onshow事件   
obj.onShow = objOnShow;//无法将userName这个变量传递进去   
obj.show();   
</script>  


<script language="javascript" type="text/javascript" >
function User(){
}
User.prototype={
show:function(){
this.onShow();//触发onShow事件
},
onShow:function(){}//定义事件接口
}
var obj = new User();
//创建obj的onshow事件处理程序
function objOnShow(userName){
alert("hello,"+userName);
}
//定义username变量
var userName = "plkong";
//绑定obj的onshow事件
obj.onShow = objOnShow;//无法将userName这个变量传递进去
obj.show();
</script>  上面的程序是无法传递参数进去的,为了解决这个问题,我们可以从相反的思维方式去考虑问题。不考虑怎么把参数传递进去,而是考虑如何构建一个无需参数的事件处理程序。我们看看先看看下面的函数:
/* 将参数的函数封装为无参数的函数 */  
    function createFunction(obj, strFunc)
    {   
	    var args = [];//定义args用于存储传递给事件处理程序的参数   
	    if(!obj) obj = window;//如果是全局函数则obj = window;   
	    //得到传递给事件处理程序的参数   
	    for( var i = 2; i<arguments.length; i++)   
	        args.push(arguments[i]);   
	    //用无参函数封装事件处理程序的调用   
	    /*  
	    JavaScript为函数对象定义了两个方法:apply 和 call, 它们的作用都是函数绑定到另外一个对象上运行。  
	    */  
	    return function()
	    {   
        	obj[strFunc].apply(obj, args);//将参数传递给指定的事件处理程序   
        }   
	}   

该方法将一个有参数的函数封装为一个无参数的函数,不仅对全局函数适用,作为对象方法存在的函数也是适用的。该方法首先接收两个参数:obj 和 strFunc ,obj 表示事件处理程序所在的对象; strFunc 表示事件处理程序的名称。程序中还利用了arguments对象(arguments是传递给函数的隐含参数,arguments对象存储的是实际传递给函数的参数,而且不局限与函数声明所定义的形参列表。关于arguments对象可以参考其他资料)处理第二个参数以后的隐式参数,即未定义为形参的参数,

    例如:事件处理程序

    someObject.eventHandler = function(_arg1, _arg2){

                   //事件处理代码


}

    应该调用:creatFunction(someObject, "eventHander", arg1, arg2);

    这样就返回一个无参数的函数,在返回的函数中已经包括了传递进去的参数。如果是全局函数作为事件处理程序,事实上它是window 对象的一个方法,所以可以传递window对象作为obj参数,为了更清晰一点,也可以指定obj为null, creatFunction函数内部会自动认为该函数是全局函数,从而自动吧obj赋值为window。最后完成的代码如下:
function User()
	{   
	}   
	User.prototype=
	{   
	    show:function()
	    {   
	        this.onShow();//触发onShow事件   
	    },   
	    onShow:function(){}//定义事件接口   
	}   
	var obj = new User();   
	//创建obj的onshow事件处理程序   
	function objOnShow(userName)
	{   
	    alert("hello,"+userName);   
	}   
	//定义username变量   
	var userName = "plkong";   
	//绑定obj的onshow事件   
	//obj.onShow = objOnShow;//无法将userName这个变量传递进去   
	obj.onShow = createFunction(null, "objOnShow", userName);   
	obj.show();  
分享到:
评论
1 楼 cheaizheng 2008-07-17  
 

相关推荐

    委托、事件与Observer设计模式

    以实例方式详细讲述了委托、事件与Observer设计模式,每一步都有注释说明,便于大家理解。 适合新手入门理解什么是委托、事件与Observer设计模式

    委托和事件-观察者设计模式

    委托和事件-观察者设计模式 初学者对事件委托,观察模式的理解!

    C嵌入式编程设计模式

    《C嵌入式编程设计模式》针对嵌人式系统中从内存访问到事件调度,从状态机设计到安全性可靠性保证,对系统的设计以及性能表现的方方面面进行了详细阐述。《C嵌入式编程设计模式》采用uml图形化解释,直观清晰;所有...

    详解C#委托,事件,Observer设计模式

    详解C#委托,事件,Observer设计模式 1.将方法作为方法的参数 2.将方法绑定到委托 3.事件的由来 4.事件和委托的编译代码 5.委托、事件与Observer设计模式 6..Net Framework中的委托与事件

    Brew的事件机制及设计模式

    Brew的事件机制及设计模式,Brew的事件机制及设计模式

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

    C++从0实现百万并发Reactor服务器完结13章

    Reactor 模式也叫做反应器设计模式,它是一种为处理服务请求并发提交到一个或者多个服务处理程序的事件设计模式。当请求抵达后,服务处理程序使用解多路分配策略,然后同步地派发这些请求至相关的请求处理程序。 ...

    软件设计模式与体系结构(讲解+代码)

    上篇:软件设计模式例子代码  【例2.2】简单工厂方法模式-汽车保险  【例2.3】工厂方法模式-汽车保险  【例2.4】抽象工厂模式-房屋信息  【例2.5】生成器模式-房屋信息  【例2.6】单例模式-互联网连接  ...

    C#中的委托、事件和Observer设计模式使用方法示例

    此文档有助于学习C#委托、事件和Observer设计模式。

    实例解析labview 设计模式

    通过实例VI 讲解labview 的三种设计模式,生产消费者模式、事件状态机、状态机模式。

    Java设计模式之监听器模式实例详解

    主要介绍了Java设计模式之监听器模式,结合实例形式较为详细的分析了java设计模式中监听器模式的概念、原理及相关实现与使用技巧,需要的朋友可以参考下

    面向对象初学者必须掌握的几种设计模式

    观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是学习Spring的基础 命令模式 Command:Struts框架的基石 单例模式 Singleton:最简单的设计模式,大量...

    一种JavaScript的设计模式

    一种JavaScript的设计模式 //简单的类的设计模式 //定义一个类class1 function class1() { //构造函数 } //通过指定prototype对象来实现类的成员定义 class1.prototype... //简单的带参数的事件设计模式 &lt;scrip

    设计模式系列之观察者模式

    观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件...

    swift-TopicEventBus易于使用是发布-订阅设计模式的类型安全方式实现

    发布 - 订阅设计模式实现框架,具有按主题发布事件的能力

    掌握Spring设计模式:Java工程师必备指南

    作为一个资深Java工程师,我发现《Spring 设计模式总结》PDF非常精彩,它深入剖析了Spring框架中的关键设计模式。例如,简单工厂模式通过BeanFactory展现,实现了松耦合和动态对象创建。工厂方法模式则通过...

    KWIC 程序示例 事件风格 观察者模式

    KWIC 程序示例 事件风格 观察者模式的程序代码,使用的是Java语言。

Global site tag (gtag.js) - Google Analytics