面向对象的 JavaScript 编程

news/2024/12/23 14:59:52 标签: javascript, function, timer, class, prototype, vbscript
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left">
    Javascript
对于做过 Web 程序的人不应该是陌生,初期是用来做一些简单的 FORM 验证,基本上是在玩弄一些技巧性的东西。 IE 4.0 引入了 DHTML ,同时为了对抗 Netscape Javascript, 提出了自己的脚本语言 JScript ,除了遵循 EMAC 的标准之外,同时增加了许多扩展,如下要提到的 OOP 编程就是其中的一个,为了命且概念,我以下提到的 Javascript 都是 Microsoft Internet Explorer 4.0 以上实现的 JScript, 对于 Netscape ,我没有做过太多的程序,所以一些的区别也就看出来。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
    Javascript
不是一个支持面向对象的语言,更加算不上一个开发平台,但是 Javascript 提供了一个非常强大的基于 prototype 的面向对象调用功能,你可以在你自己需要的地方使用他们。因此 , 如何使用对象?本文尽可能从 Javascript 面向对象实现原理出发,解析清楚它的工作模型。在了解这些模型之后,你可以在自己的脚本库中编写一些实现代码,然后在其他地方调用。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Javascript 的语法和 C++ 很接近,不过在类实现中没有使用关键字 Class, 实现继承的时候也没有采用传统的 Public 或者 Implement 等等所谓的关键字来标示类的实现。这样的情况下,可能有就有人会问,如何编写 Javascript Class ,如何实现继承。我开始也是百思不得其解,后来看了 MSDN, 才知道采用了 prototype 来实现,包括继承和重载,也可以通过这个关键字来实现。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Javascript 的函数很奇怪,每个都是默认实现了 Optional 的,即参数都可以可选的, class="tags" href="/tags/FUNCTION.html" title=function>function a(var1,var2,var3), 在调用的过程中 a(),a(value1),a(value1,value2) 等等的调用都是正确的,至少在即使编译部分可以完整通过,至于其它,只是和函数的实现逻辑比较相关了。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    以下就 JS 对于类的实现、继承、重载详细介绍其实现方式。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    1 。实现

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Js 类的实现就通过函数直接实现的,每个函数可以直接看成 class ,如下代码

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    class="tags" href="/tags/FUNCTION.html" title=function>function ClassTest1(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        ...//implement code

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    var a=new ClassTest1

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">   

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    class="tags" href="/tags/FUNCTION.html" title=function>function ClassTest2(var1){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        ...//implement code

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    var b=new ClassTest("value")

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    对于类的属性,可以通过两种方式实现

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    1 this."<Property or Method" 的方式实现,在类声明函数中直接给出函数的实现,如 this.Add=new class="tags" href="/tags/FUNCTION.html" title=function>function(strUserName,strPassword) 这样的方式调用,编写的方式在 Class Function 中调用。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    2 通过 ClassFunction.prototype.[FunctionName]=class="tags" href="/tags/FUNCTION.html" title=function>function(var1,var2...){//todo} 这样的方式完成调用。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    这两种方式从目标来看是一致的,按照我个人的观点来看,区别的只是在于实现方式,通过 this.propertyName 的方式来创建, Jscript 自动创建了 property 或者 method 的入口,不过从程序的角度而言,还是使用 prototype 的关键字实现比较灵活。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">   

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    另外 Javascript 也可以和我们 C++ 中那种嵌套声明的方法来声明 ,C++ 实现的方法如下

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Public Class ClassName:ParentClass{

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        Public DataType FunctionName(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        Public Class ClassName{

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">            Public DataType FunctionName(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">            }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Javascript 当中,当然不存在 class 这样的关键字了 , 所以实现起来有点戏剧性,不过仍然为一个非常巧妙的实现。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    class="tags" href="/tags/FUNCTION.html" title=function>function className(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        //Property Implement

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        this.UserName="blue";

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        //Method Implement

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        this.Add=new class="tags" href="/tags/FUNCTION.html" title=function>function(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        //Sub Class Implement

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        class="tags" href="/tags/FUNCTION.html" title=function>function SubClassName(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">            this.PropertyName="hi"           

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        //sub class method implement

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        SubClassName.prototype.Change=class="tags" href="/tags/FUNCTION.html" title=function>function{

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    //Main Class Method Implement

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    className.prototype.Delete=class="tags" href="/tags/FUNCTION.html" title=function>function(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    如上的代码大致演示了 Javascript 类中属性和方法的实现,另外有一点比较困惑,整个 class 中都是 public 的,没有关键字 private 之类的可以控制某些方法是否隐藏,那么在我们编写代码实现的规范中,我看国外一些程序员都是使用 _class="tags" href="/tags/FUNCTION.html" title=function>functionName 这样子为函数命的方法来区分,但是在调用过程中实际还可以调用的。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    实现了属性和方法,剩下的就是 Event 的实现了,我查找了许多资料,包括整个 MSDN 关于 JScript 的参考,都没有看到一个很好的模型关于事件实现的,后来参考了一些站点编写 HTA(HTML Component, 有空我会写一些相关的文章)的实现,借助于比较扭曲(我个人认为)的方法可以大致的实现基于事件驱动的功能。大致的思路是这样子的:

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    1 . 将所有的事件定义成属性,只要简单的声明就可以

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    2 . 在需要触发事件的代码中判断事件属性是否是一个函数,如果是函数,直接执行函数代码,如果是字符串,那么执行字符串函数,通过 eval(str) 来执行。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    3) . 在类的实例当中注册事件函数。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    为了简单说明如上的思路,采用 class="tags" href="/tags/TIMER.html" title=timer>timer 这样简单的例子来表述如上的所提到的内容,如果只是为了简单的实现 class="tags" href="/tags/TIMER.html" title=timer>timer 的功能, Javascript setInterval 函数就可以满足全部的要求,如下的代码只是用来说明 Timer 的工作原理。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//Class For Timer
class="tags" href="/tags/FUNCTION.html" title=function>function Timer(iInterval){
 //if not set the class="tags" href="/tags/TIMER.html" title=timer>timer interval ,then defalut set to 500ms
 this.Interval=iInterval || 500;
 this._handleInterval;
 this.TimerEvent=null
 class="tags" href="/tags/FUNCTION.html" title=function>function Start(){
  if(this.Interval!=0){
   this._handleInterval=setInterval("TimerCallBack()",this.Interval);
  }
 }
 class="tags" href="/tags/FUNCTION.html" title=function>function Start(){
  clearInterval(this._handleInterval);
 }
 class="tags" href="/tags/FUNCTION.html" title=function>function TimerCallBack(){
  if (typeof this.TimerEvent=="class="tags" href="/tags/FUNCTION.html" title=function>function"){
   this.TimerEvent();
  }
  else if(this.TimerEvent!=null && this.TimerEvent.length>0){
   eval(this.TimerEvent);
  }
 }

//Code for Instance
var t=new Timer(3);

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//------------------------------------//

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//1.
t.TimerEvent=class="tags" href="/tags/FUNCTION.html" title=function>function(){
//todo
}

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//2.
t.TimerEvent="alert(/"hello/")";

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//3.

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">t.TimerEvent=tTimerCall;

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">//----------------------------------//
t.Start();
t.Stop();

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">class="tags" href="/tags/FUNCTION.html" title=function>function tTimerCall(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt">}

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    实际工作代码是在 TimerCallBack() 上面实现,事件触发作为属性的方式来实现,在应用实例中,代码提供了三种方法去调用事件,不过在事件的回调当中,我还没有想到如何可以带参数,只有才各自的实现当中访问各自需要的属性才能够实现全部的要求。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    2 。继承。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    刚采用了大篇幅的文字去介绍如何实现 Javascript 的各种实现,也就是从逻辑上完成了一个封装 class 的实现,从某种意义上来说, class 的实现是真正脚本编程中使用最多的部分,不过如果只是要完成如上的功能,使用 VBScript 来编写更能更加清晰,毕竟 VBscript 提供了 class 关键字,同时提供了 public private 这两个关键字,可以清晰的将公共和私有对象分离,至于事件的实现,也可以采用类似 Javascript 实现的思路,只是对于函数的引用需要采用 GetRef 这个函数,具体的用法可以参考 scripting reference,MSDN 里头也有详细的介绍,而 Javascript 强大至于在于如下要说的了,虽然具体的东西可能不多。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    如上所言,我们已经完成了一个基本的类实现 Timer ,现在要做的是重新编写这个类,我们简单的只是想在这个类之中加入一个方法,提供当前的系统时间,方法的名称为 getSystemDate, 显然如果全部重新编写,那就失去了我这里说的意义了。先看看如下的实现。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    class="tags" href="/tags/FUNCTION.html" title=function>function NewTimer(iInterval){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        //call super

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        this.base=Timer;

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        this.base iInterval);       

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    NewTimer.prototype=new Timer;

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    NewTimer.prototype.getSystemDate=class="tags" href="/tags/FUNCTION.html" title=function>function(){

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        var dt=new Date();

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">        return dt.getYear()+"-"+dt.getMonth()+"-"+dt.getDay()

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    }

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">   

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    上述代码实现了 NewTimer 类,从 Timer 继承, Javascript 没有使用 或者 java public 那样类似的关键字,只是通过 newclassname.prototype=new baseclass 这样的方法来完成,同时 NewTimer 实现了 getSystemDate 的方法,在 NewTimer 的初始化函数中,我使用了 this.base=Timer ,是为了引用父类的实现,不过在对于父类其他实现函数的调用,到现在我没有找到一个确定的方法,是否通过 this.base.start() 那样来调用还是其他的,如果有谁比较清楚的,麻烦告诉我,另外在 netscape 的站点上,我查到有一个特殊的 "__proto__" 的属性好像是对于父类的直接引用,不过具体的我也没有尝试过,在 msdn 中也没有看到对于 __proto__ 的支持。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">   

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    3 。重载

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    或许这个是 OOP 编程中比较复杂的地方了,在 Javascript 的实现中有点无奈,也就是通过 prototype 的方式来完成的,不过因为我不清楚如何调用父类的实现函数,那么在重载中只能够重新编写所有的实现了,另外就是在实现中实例化一个父类,然后通过调用它来返回需要的东西。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Javascript 中所有的对象都是从 Object 继承下来的, object 提供了 toString() 的方法,也就是说如果调用 alert(objInstance) 这样的过程,实际上是调用了 alert(objInstance.toString()) 的方法,如果没有编写实现, object 默认的 toString() 都是 "object object" 这样子的,在许多地方需要重载这个函数的,比如 Timer, 如果我们希望 var ins=new Timer(5);alert(ins) 调用得到的是 interval 的值 5 ,那么就需要重新编写 toString() 方法了

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    Timer.prototype.toString=class="tags" href="/tags/FUNCTION.html" title=function>function(){ return this.Interval};

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">    以上代码实现之后 alert(ins) 得到的就是 5 了。

class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> 


http://www.niftyadmin.cn/n/1153075.html

相关文章

jquery打造自定义控件(原创)

本人第一次发表文章&#xff0c;不足之出请大家多多包涵 下面是一个combox的代码 /// <reference path"../Js/jquery-1.7.2.min.js" />$.extend({//下拉列表框qyjcombox: function (select) {//这里是初始化var htmlstr "<div class\"boxwrap\…

LeetCode 9. Palindrome Number(c语言版)

题目&#xff1a; Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward. Example 1: Input: 121 Output: trueExample 2: Input: -121 Output: false Explanation: From left to right, it reads -121. Fro…

生产者--消费者模式

生产者--消费者模式 1、示例&#xff1a; class Resource{private String name;private int count 1;private Boolean flag false;public synchronized void set(String name){if(flag)try {this.wait();//this代表调用函数线程} catch (InterruptedException e) {}this.name…

C++中的预定义宏

C/C&#xff0b;&#xff0b;宏大全(转载,原贴地址http://www.cnblogs.com/sevencat/archive/2004/06/10/14872.html)一、标准预定义宏The standard predefined macros are specified by the relevant language standards, so they are available with all compilers that impl…

PHP 7.0 中各种 Hash 速度比较

概述 最近需要对一些很长的 msyql 字段做索引优化。讨论下来有几种解决方案带确定&#xff0c;其中一个就是对现有字符做 hash&#xff0c;然后对此hash和原始字符做联合索引。就此有了 hash 效率比较的需求&#xff0c;文中使用 php 对一段字符做 200 万次 hash&#xff0c;并…

NPOI兼容 excel2003,2007版本

根据项目需要&#xff0c;需要对excel进行导入导出&#xff0c;所以选择NPOI&#xff0c;优点在这里就不详细介绍了&#xff0c;下面进入正题。 1 public int Import(string path)2 {3 IList<Student> list new List<Student>();4 5 …

解决 Zend Studio For Linux 乱码和UBUNTU下不显示(白屏)问题

不显示界面问题&#xff1a;打开后不能正常显示&#xff0c;只有标题栏正常解决&#xff1a;用vi打开Zend_Development_Environment&#xff08;和你选择安装的路径有关&#xff0c;找下&#xff09;&#xff0c;打开后输入/set nu在输入1693在其附近会有类似下面的代码&#x…

CCRD_TOC_2008年第3期

中信国健临床通讯 2008年第3期 目 录 银屑病和银屑病关节炎 1. 国际皮肤病专家呼吁重视生物制剂治疗银屑病 原文: http://pharmatimes.com/forums/forums/t/855.aspx 2. 案例报道&#xff1a;依那西普有效治疗泛发性脓疱型银屑病 Esposito M, et al. Dermato…