asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0
 发表于 2004-11-12 10:22:04  按此观看桃花岛主的个人资料 按此发邮件给桃花岛主 访问桃花岛主的主页 桃花岛主 的 oicq 是9202142,查看 9202142 的资料 收藏该主题供以后查看 发送悄悄话给桃花岛主 搜索桃花岛主的所有帖子 引用这个帖子回复  举报不良信息
面向对象的Jscript

  在web页面的客户端应用中,js已经成为不可缺少的部分。传统方式对js的应用完全基于过程模型,在这种模型里,普通语句及全局函数的使用最为普遍。当代码的数量逐渐增加,整个项目的维护就变得困难,逻辑也渐渐超出设计者的掌控,这个时候,我们需要借用软件工程的观念来管理项目。现代软件工程的根基是组件化、对象化的程序设计,由UML设计图指导的程序设计过程有条不紊地进行着。令人苦恼的是,当现代软件工程的理念渗入web项目的时候,却遇到了很大的问题,几乎没有办法发挥它的威力。

  问题的根源是什么?是我们没有一种有效的方式来组织js程序,使得它能够遵循一些基本的面向对象思想。然而,js并非没有办法体现出这些思想,本文试图用某些特殊的组织方式来让js符合基本的面向对象特性,为进一步应用软件工程的某些设计模式作铺垫。

  Jscript中内置了一些类,例如String、Array、Math等,用户可以直接从这些类实例化出对象,并使用其中的属性和方法。单凭这一点,不能说js符合面向对象语言的特征。一种面向对象的语言,应当具有封装,继承,多态等基本特性。Jscript并没有直接提供实现这些特性的方法,但是,也并非完全无法实现。

一、Js中的封装
  一种面向对象的语言应当允许用户创建自定义类型,这一点js做到了,只是它的自定义类型不是用class限定,而是作为function,这个function的作用相当于其他语言中的构造函数。在自定义类型中,用户可以添加属性、方法。但是,js中并未显式提供public、private、protected等访问限定,也没有提供static之类的作用域限定。下面通过几个例子,逐一说明创建自定义类型及实现各种限定的方法。

示例1-1:该例子演示了创建及使用包含属性和方法的自定义类型的过程。本例子中,我们创建了一个名为MyClass的类,其中包含了一个Name属性和一个showName方法,然后将这个类实例化,即可调用其中的方法,使用其中的属性。注意,在类中定义的方法和属性应当使用this关键字绑定到这个类,调用时使用绑定名字来访问,而不是通过实际名字。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


示例1-2:该例子演示了public和private访问限定的实现。本例子中,我们修改了上个例子中的MyClass类,将其扩充为两个属性和两个方法。注意到PrivateName的声明,它并没有绑定到这个类,因此只具有局部作用域,生命期仅在本类中,如果在类的方法中调用它的话,是可以正常调用的(调用的时候不加this关键字)。同理,没有绑定的方法也只能在类的内部调用。因此,js中的public与private限定可以通过这种方式来实现。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  在这里,需要注意到一个现象,既然js把类本身作为一个构造函数,它在实例化的时候将逐个执行其中的语句,保留其中的方法定义,一直把整个函数执行完。因此,本例子中注释掉的writePrivateName();语句如果正常执行,将在MyClass类实例化的时候运行。

示例1-3:该例子演示了static限定的实现。本例子中,我们将MyClass类修改为带一个普通属性、一个静态属性和两个静态方法的类。这个类可以被实例化,所能够访问的仅仅是在类中定义的普通属性。当不实例化,通过类名访问的时候,可以访问类中的静态方法和静态属性,静态方法只能访问静态属性。与C++类似,静态成员的初始化需要在类的外面进行。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  通过以上三个示例,我们能够看出,js很好地支持了封装,并且支持了基本的访问限定。

二、Js中的继承
  继承是面向对象语言中扩展已有类型的一种有效途径,js没有提供用于实现继承的extends关键字或者“:”操作符,但是,由于它是一种动态语言,可以在需要的时候添加属性和方法。以下示例中继承机制的实现均基于这种原理。

示例2-1:该例子演示了从基类派生出一个子类的方法。子类中创建了基类的对象,为它添加了新的属性和方法,然后将它作为子类构造函数的结果返回出去,得到子类对象。子类对象比基类对象多了一些属性和方法,分配到了更多内存空间。注意到每次输出的constructor属性的值,发现它们两次返回的都是基类的构造函数,这并不奇怪,因为子类的构造函数最后返回的是添加了新属性、新方法的基类对象,js执行环境仍然会认为它是一个基类对象。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


示例2-2:该例子演示了从两个不同基类派生出一个子类的方法。子类中分别创建了两个基类的对象,将其中一个的所有属性和方法添加到另外一个上,然后将后者作为子类构造函数的结果返回出去,得到子类对象。通过这种途径,变相地实现了多重继承。这里有一个注意点,不同的基类中如果包含同名变量或方法,需要自己指定以哪个作为实际绑定。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  通过以上两个示例能够看出,js其实支持了继承的机制,只不过这种机制需要更多的手工控制。

  既然提到继承,顺便讨论一下protected限定,它的作用是使得被限定的变量或方法不能被类的实例调用,但是能够被派生类调用。写这篇文章的时候本人曾经花了不少时间来考虑是否有可能使用js模拟出这种限定,后来发现,既然public跟private限定是通过指定绑定来实现的,那么,没法创建一种介于绑定和不绑定之间的关系,也就不好用这种方式模拟。再转念一想,protected限定几乎都是实现在编译型的语言中。在目标代码或者中间代码层次,这种限定非常重要,它能够有效配合软件工程理论进行开发,但是js是纯解释型语言,源代码公开的级别,不存在有效的模块保护机制,任何人可以随意修改代码,这样,protected关键字完全没有用武之地。

  C++等语言拥有一种特殊类:接口。接口的作用是为类提供规范、约束,它规定了继承这个接口所必须实现的方法集合。我们当然可以实现这样一个机制,当类继承接口的时候,检查它是否实现了接口中的全部方法,或者是否提供了这些方法的声明,但这种做法并不必要。当继承这个接口的时候,根据上面实现的这种继承机制,将会直接创建接口的一个对象(有的语言中禁止把接口实例化),这个时候,它已经包含了接口中所定义的方法集合,即使不重新定义这些方法并绑定,他们显然已经被声明了,而且,js不提供一个机制用于识别抽象方法,接口中的方法是否已被实现也无从得知。

三、Js中的多态
  多态能够让对象在运行时决定实际调用的方法体。由于js是一种动态语言,支持运行时绑定,讨论它的多态实际上并没有太大意义。Js不支持virtual关键字,而virtual关键字在现在的js里面也不会有明显用处。最根本的一点,js能够在运行时改变数据类型,可以随时根据新类型来取得它所拥有的方法,而忽视原有类型的影响。

示例3-1:该例子创建了一个基类跟一个子类,拥有一个同名方法,分别将基类和子类实例化并调用这个方法,显示的结果将随着方法所属类的不同而不同。原因很简单,因为例子使用的这种“继承”机制本身就是利用js语言的动态特性实现的,在一个类实例化的时候,它已经知道自己拥有哪些方法,而且,它也不关心这些方法从哪个类继承,只是将它们作为普通的成员方法来调用,所以,每一个类调用的同名方法都是属于自己的那个。再者,js是弱类型语言,它的变量声明的时候并不知道自己的类型,也并不知道将要被初始化成什么类型,赋予它什么类型的值,它就是什么类型的变量。本例子中分别注释掉的两段语句就说明了这个问题:Js在运行时既能够将子类变量赋给基类变量(这个特性在C++等语言中正是实现多态的关键),也可以将基类变量赋给子类变量(一般在静态语言中不允许,因为缺少附加信息)。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


四、总结
  综合以上分析,js勉强能够算是一种面向对象的语言,因此,也可以将一些软件工程的思想应用到开发中,使得整个项目的架构稳定,逻辑清晰。51js论坛的万常华前辈作出了很大的努力,他将js的面向对象特性设计成一种规则,模仿java的包-类结构,做出了一些由这种规则支撑的常用类库,经过一段时间的努力和完善,已经可以初步进行应用了。

  附记:写这篇文章来源于一个灵感,在学习设计模式的时候,我联想到目前web程序设计中的诸多不规范情况,多数人依然使用传统的过程化结构来控制整个项目,当项目越做越大的时候常有力不从心的感觉。混乱的设计、到处隐藏的bug,这一切注定无法避免么?于是,我尝试用面向对象的思路来重新看待js,并期望以后能够在这个基础上,将一些设计模式应用到web程序设计上来,在界面设计与事务处理分离的前提下,让整个项目的架构趋于合理、稳定。写这篇文章的时候,我并不知道到底我对js了解了多少,也不知道我的理解是否包含了严重的错误,这一切只是一个探索,也希望大家能够赐教,或者给出好的建议。本人是东南大学计算机系大四的学生,碰巧的是,这学期软件体系结构课程老师要求自由选题写一篇论文,花了一个星期时间,希望没有让老师失望,呵呵。


情愿用一生时间守护一个诺言,不需要海誓山盟,只要你懂,我懂。
renaski

洛林
积分:6548
发贴:1986
来自:上海曹杨新村
注册:2003-09-22
 发表于 2004-11-12 10:32:25  按此观看renaski的个人资料 按此发邮件给renaski 发送悄悄话给renaski 搜索renaski的所有帖子 引用这个帖子回复  举报不良信息
我等我们老师出什么论文了。


承接各类网站,应用程序开发业务。Flash,.Net,Asp,vb,Xml,MsSql,Oracle,DB2,Access,Php,MySql,Jsp,J2EE,软件架构设计,网站美工,网站建站一条龙服务。手机SP端口(短信服务),彩信服务,银行支付系统,Pos机,公司注册,经营许可证,ICP证,BBS证,等等业务。
msn:renaski@hotmail.com
桃花岛主

终级用户
积分:2853
发贴:714
来自:南京
注册:2002-12-20
 发表于 2004-11-12 11:05:13  按此观看桃花岛主的个人资料 按此发邮件给桃花岛主 访问桃花岛主的主页 桃花岛主 的 oicq 是9202142,查看 9202142 的资料 发送悄悄话给桃花岛主 搜索桃花岛主的所有帖子 引用这个帖子回复  举报不良信息
附带强调一下,js不是真的支持多态,我提到的多态跟实际上的多态有本质区别,防止误导别人,多谢51js的泣红亭版主提醒。


情愿用一生时间守护一个诺言,不需要海誓山盟,只要你懂,我懂。
littlephenix

初级用户
积分:75
发贴:19
来自:东南大学
注册:2004-11-02
 发表于 2004-11-12 11:44:45  按此观看littlephenix的个人资料 按此发邮件给littlephenix 发送悄悄话给littlephenix 搜索littlephenix的所有帖子 引用这个帖子回复  举报不良信息
楼主可否知道js中可否对一个类的对象绑定监听器?使得它可以响应自己定义的事件?js研究的不深,大三时为了参加学生会的那个flash比赛突击过as,actionscript里面有监听器类可以继承和派生,js有吗?


我在跑。路的尽头,也许不如我所愿,可是我必须为了生命奔驰……
桃花岛主

终级用户
积分:2853
发贴:714
来自:南京
注册:2002-12-20
 发表于 2004-11-12 12:55:15  按此观看桃花岛主的个人资料 按此发邮件给桃花岛主 访问桃花岛主的主页 桃花岛主 的 oicq 是9202142,查看 9202142 的资料 发送悄悄话给桃花岛主 搜索桃花岛主的所有帖子 引用这个帖子回复  举报不良信息
js可以为事件指定处理函数的,有点像C里面的函数指针或者C#的delegate,不过似乎没有专门的监听器类,怎么自定义事件我也不知道。


情愿用一生时间守护一个诺言,不需要海誓山盟,只要你懂,我懂。
cid73

超级用户
积分:381
发贴:99
来自:
注册:2003-01-02
 发表于 2004-11-12 15:50:38  按此观看cid73的个人资料 按此发邮件给cid73 发送悄悄话给cid73 搜索cid73的所有帖子 引用这个帖子回复  举报不良信息
特别注意到标题是 JScript, 而不是 JavaScript 或 ECMAScript, 请问会否使用到微软的私有方法和属性? 代码能是否在所有浏览器上通过?
桃花岛主

终级用户
积分:2853
发贴:714
来自:南京
注册:2002-12-20
 发表于 2004-11-12 17:25:12  按此观看桃花岛主的个人资料 按此发邮件给桃花岛主 访问桃花岛主的主页 桃花岛主 的 oicq 是9202142,查看 9202142 的资料 发送悄悄话给桃花岛主 搜索桃花岛主的所有帖子 引用这个帖子回复  举报不良信息
呵呵,因为我没有做过这样的测试,也不知道它在其他浏览器上会有什么结果,才不敢说javascript的,大家要是有兴趣,不妨测试一下啊。


情愿用一生时间守护一个诺言,不需要海誓山盟,只要你懂,我懂。
panliu888

Prime Bin Full
现任版主
积分:14777
发贴:4409
来自:潍坊
注册:2003-01-21
 发表于 2004-11-14 11:00:45  按此观看panliu888的个人资料 按此发邮件给panliu888 发送悄悄话给panliu888 搜索panliu888的所有帖子 引用这个帖子回复  举报不良信息
flash的 addEventListener


页面:点这儿参观


www.pubcms.com

Blueidea Web Team
Moderator Of Dreamweaver & Javascript
littlephenix

初级用户
积分:75
发贴:19
来自:东南大学
注册:2004-11-02
 发表于 2004-11-15 08:58:51  按此观看littlephenix的个人资料 按此发邮件给littlephenix 发送悄悄话给littlephenix 搜索littlephenix的所有帖子 引用这个帖子回复  举报不良信息
呵呵,flash中注册和绑定监听器和java差不多的^_^


我在跑。路的尽头,也许不如我所愿,可是我必须为了生命奔驰……
zgws744530

初级用户
积分:8
发贴:2
来自:
注册:2004-10-22
 发表于 2004-11-16 17:32:17  按此观看zgws744530的个人资料 按此发邮件给zgws744530 发送悄悄话给zgws744530 搜索zgws744530的所有帖子 引用这个帖子回复  举报不良信息
好好谢谢
zgws744530

初级用户
积分:8
发贴:2
来自:
注册:2004-10-22
 发表于 2004-11-17 15:14:29  按此观看zgws744530的个人资料 按此发邮件给zgws744530 发送悄悄话给zgws744530 搜索zgws744530的所有帖子 引用这个帖子回复  举报不良信息
斑竹,能不能推荐一两本好的学习Javascript的书。谢谢!
pantong

高级用户
积分:204
发贴:54
来自:
注册:2004-11-25
 发表于 2004-11-28 17:12:12  按此观看pantong的个人资料 按此发邮件给pantong 发送悄悄话给pantong 搜索pantong的所有帖子 引用这个帖子回复  举报不良信息
谢谢 就是看 的 不太明白

shanban

初级用户
积分:149
发贴:41
来自:
注册:2002-12-12
 发表于 2004-11-30 20:01:28  按此观看shanban的个人资料 按此发邮件给shanban 发送悄悄话给shanban 搜索shanban的所有帖子 引用这个帖子回复  举报不良信息
不知道是干什么用的
kafeifei

初级用户
积分:31
发贴:8
来自:
注册:2004-12-12
 发表于 2004-12-13 04:57:01  按此观看kafeifei的个人资料 按此发邮件给kafeifei 发送悄悄话给kafeifei 搜索kafeifei的所有帖子 引用这个帖子回复  举报不良信息
不知道为什么MS没有砍掉flash
flash可以弹新窗口,或者直接跳转,比如做一个直接跳转的FLASH,贴到论坛上,以后只要点进这个帖子马上跳转到指定地点(比如一个有病毒的页面)
我觉得这个已经侵犯了IE的“人权”。
桃花岛主

终级用户
积分:2853
发贴:714
来自:南京
注册:2002-12-20
 发表于 2004-12-13 12:27:03  按此观看桃花岛主的个人资料 按此发邮件给桃花岛主 访问桃花岛主的主页 桃花岛主 的 oicq 是9202142,查看 9202142 的资料 发送悄悄话给桃花岛主 搜索桃花岛主的所有帖子 引用这个帖子回复  举报不良信息
M$要是砍flash,估计不是这种砍法。它直接发布一个activeX控件,或者干脆改进IE,包含了flash的全部功能,而不是依赖现在的脚本,全新增强客户端编程,那flash日子就难过了,applet也要挂了


情愿用一生时间守护一个诺言,不需要海誓山盟,只要你懂,我懂。
伤心一滴泪

初级用户
积分:89
发贴:43
来自:
注册:2004-02-29
 发表于 2004-12-14 15:24:27  按此观看伤心一滴泪的个人资料 按此发邮件给伤心一滴泪 访问伤心一滴泪的主页 发送悄悄话给伤心一滴泪 搜索伤心一滴泪的所有帖子 引用这个帖子回复  举报不良信息
不知道为什么MS没有砍掉flash
flash可以弹新窗口,或者直接跳转,比如做一个直接跳转的FLASH,贴到论坛上,以后只要点进这个帖子马上跳转到指定地点(比如一个有病毒的页面)
我觉得这个已经侵犯了IE的“人权”。


我暫成這种說法


心,痛了,沉了,睡了,死了。。。
不在郁闷中死亡,就在郁闷中爆发,而我却在郁闷中彷徨,心不知方向
歡迎訪問我的世界 傷心世界
[img]http://www.5xp.net/winlmh/images/logo.gif[/img]
laoding12

终级用户
积分:3262
发贴:1133
来自:福州.中国
注册:2004-07-14
 发表于 2004-12-15 15:40:31  按此观看laoding12的个人资料 按此发邮件给laoding12 发送悄悄话给laoding12 搜索laoding12的所有帖子 引用这个帖子回复  举报不良信息
现在是网页多媒体的时代,砍MS不可能吧!


[该签名使用不良语言 已被经典论坛过滤]
hbweiqiang

初级用户
积分:8
发贴:2
来自:
注册:2004-12-20
 发表于 2004-12-22 19:02:24  按此观看hbweiqiang的个人资料 按此发邮件给hbweiqiang 发送悄悄话给hbweiqiang 搜索hbweiqiang的所有帖子 引用这个帖子回复  举报不良信息
在网页中怎么插入音乐不知道 把代码插到那 个地方楼主帮助
hotrain

初级用户
积分:10
发贴:3
来自:
注册:2005-01-02
 发表于 2005-01-03 19:38:15  按此观看hotrain的个人资料 按此发邮件给hotrain 发送悄悄话给hotrain 搜索hotrain的所有帖子 引用这个帖子回复  举报不良信息
js能不能挂接数据库呀
mthgenghao

初级用户
积分:4
发贴:4
来自:
注册:2005-01-02
 发表于 2005-03-14 10:45:48  按此观看mthgenghao的个人资料 按此发邮件给mthgenghao 发送悄悄话给mthgenghao 搜索mthgenghao的所有帖子 引用这个帖子回复  举报不良信息
曾经看过这篇文章,觉得不错,后来竟然找不到了,很是遗憾,多谢楼主的大作,是我受益匪浅


站长点击这里,加入快搜给您带来丰厚利润
Hydralisk

初级用户
积分:23
发贴:6
来自:
注册:2005-07-19
 发表于 2005-08-03 08:16:27  按此观看Hydralisk的个人资料 按此发邮件给Hydralisk 发送悄悄话给Hydralisk 搜索Hydralisk的所有帖子 引用这个帖子回复  举报不良信息
桃花岛主在上个帖子中说
引用:
面向对象的Jscript

  在web页面的客户端应用中,js已经成为不可缺少的部分。传统方式对js的应用完全基于过程模型,在这种模型里,普通语句及全局函数的使用最为普遍。当代码的数量逐渐增加,整个项目的维护就变得困难,逻辑也渐渐超出设计者的掌控,这个时候,我们需要借用软件工程的观念来管理项目。现代软件工程的根基是组件化、对象化的程序设计,由UML设计图指导的程序设计过程有条不紊地进行着。令人苦恼的是,当现代软件工程的理念渗入web项目的时候,却遇到了很大的问题,几乎没有办法发挥它的威力。

  问题的根源是什么?是我们没有一种有效的方式来组织js程序,使得它能够遵循一些基本的面向对象思想。然而,js并非没有办法体现出这些思想,本文试图用某些特殊的组织方式来让js符合基本的面向对象特性,为进一步应用软件工程的某些设计模式作铺垫。

  Jscript中内置了一些类,例如String、Array、Math等,用户可以直接从这些类实例化出对象,并使用其中的属性和方法。单凭这一点,不能说js符合面向对象语言的特征。一种面向对象的语言,应当具有封装,继承,多态等基本特性。Jscript并没有直接提供实现这些特性的方法,但是,也并非完全无法实现。

一、Js中的封装
  一种面向对象的语言应当允许用户创建自定义类型,这一点js做到了,只是它的自定义类型不是用class限定,而是作为function,这个function的作用相当于其他语言中的构造函数。在自定义类型中,用户可以添加属性、方法。但是,js中并未显式提供public、private、protected等访问限定,也没有提供static之类的作用域限定。下面通过几个例子,逐一说明创建自定义类型及实现各种限定的方法。

示例1-1:该例子演示了创建及使用包含属性和方法的自定义类型的过程。本例子中,我们创建了一个名为MyClass的类,其中包含了一个Name属性和一个showName方法,然后将这个类实例化,即可调用其中的方法,使用其中的属性。注意,在类中定义的方法和属性应当使用this关键字绑定到这个类,调用时使用绑定名字来访问,而不是通过实际名字。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


示例1-2:该例子演示了public和private访问限定的实现。本例子中,我们修改了上个例子中的MyClass类,将其扩充为两个属性和两个方法。注意到PrivateName的声明,它并没有绑定到这个类,因此只具有局部作用域,生命期仅在本类中,如果在类的方法中调用它的话,是可以正常调用的(调用的时候不加this关键字)。同理,没有绑定的方法也只能在类的内部调用。因此,js中的public与private限定可以通过这种方式来实现。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  在这里,需要注意到一个现象,既然js把类本身作为一个构造函数,它在实例化的时候将逐个执行其中的语句,保留其中的方法定义,一直把整个函数执行完。因此,本例子中注释掉的writePrivateName();语句如果正常执行,将在MyClass类实例化的时候运行。

示例1-3:该例子演示了static限定的实现。本例子中,我们将MyClass类修改为带一个普通属性、一个静态属性和两个静态方法的类。这个类可以被实例化,所能够访问的仅仅是在类中定义的普通属性。当不实例化,通过类名访问的时候,可以访问类中的静态方法和静态属性,静态方法只能访问静态属性。与C++类似,静态成员的初始化需要在类的外面进行。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  通过以上三个示例,我们能够看出,js很好地支持了封装,并且支持了基本的访问限定。

二、Js中的继承
  继承是面向对象语言中扩展已有类型的一种有效途径,js没有提供用于实现继承的extends关键字或者“:”操作符,但是,由于它是一种动态语言,可以在需要的时候添加属性和方法。以下示例中继承机制的实现均基于这种原理。

示例2-1:该例子演示了从基类派生出一个子类的方法。子类中创建了基类的对象,为它添加了新的属性和方法,然后将它作为子类构造函数的结果返回出去,得到子类对象。子类对象比基类对象多了一些属性和方法,分配到了更多内存空间。注意到每次输出的constructor属性的值,发现它们两次返回的都是基类的构造函数,这并不奇怪,因为子类的构造函数最后返回的是添加了新属性、新方法的基类对象,js执行环境仍然会认为它是一个基类对象。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


示例2-2:该例子演示了从两个不同基类派生出一个子类的方法。子类中分别创建了两个基类的对象,将其中一个的所有属性和方法添加到另外一个上,然后将后者作为子类构造函数的结果返回出去,得到子类对象。通过这种途径,变相地实现了多重继承。这里有一个注意点,不同的基类中如果包含同名变量或方法,需要自己指定以哪个作为实际绑定。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


  通过以上两个示例能够看出,js其实支持了继承的机制,只不过这种机制需要更多的手工控制。

  既然提到继承,顺便讨论一下protected限定,它的作用是使得被限定的变量或方法不能被类的实例调用,但是能够被派生类调用。写这篇文章的时候本人曾经花了不少时间来考虑是否有可能使用js模拟出这种限定,后来发现,既然public跟private限定是通过指定绑定来实现的,那么,没法创建一种介于绑定和不绑定之间的关系,也就不好用这种方式模拟。再转念一想,protected限定几乎都是实现在编译型的语言中。在目标代码或者中间代码层次,这种限定非常重要,它能够有效配合软件工程理论进行开发,但是js是纯解释型语言,源代码公开的级别,不存在有效的模块保护机制,任何人可以随意修改代码,这样,protected关键字完全没有用武之地。

  C++等语言拥有一种特殊类:接口。接口的作用是为类提供规范、约束,它规定了继承这个接口所必须实现的方法集合。我们当然可以实现这样一个机制,当类继承接口的时候,检查它是否实现了接口中的全部方法,或者是否提供了这些方法的声明,但这种做法并不必要。当继承这个接口的时候,根据上面实现的这种继承机制,将会直接创建接口的一个对象(有的语言中禁止把接口实例化),这个时候,它已经包含了接口中所定义的方法集合,即使不重新定义这些方法并绑定,他们显然已经被声明了,而且,js不提供一个机制用于识别抽象方法,接口中的方法是否已被实现也无从得知。

三、Js中的多态
  多态能够让对象在运行时决定实际调用的方法体。由于js是一种动态语言,支持运行时绑定,讨论它的多态实际上并没有太大意义。Js不支持virtual关键字,而virtual关键字在现在的js里面也不会有明显用处。最根本的一点,js能够在运行时改变数据类型,可以随时根据新类型来取得它所拥有的方法,而忽视原有类型的影响。

示例3-1:该例子创建了一个基类跟一个子类,拥有一个同名方法,分别将基类和子类实例化并调用这个方法,显示的结果将随着方法所属类的不同而不同。原因很简单,因为例子使用的这种“继承”机制本身就是利用js语言的动态特性实现的,在一个类实例化的时候,它已经知道自己拥有哪些方法,而且,它也不关心这些方法从哪个类继承,只是将它们作为普通的成员方法来调用,所以,每一个类调用的同名方法都是属于自己的那个。再者,js是弱类型语言,它的变量声明的时候并不知道自己的类型,也并不知道将要被初始化成什么类型,赋予它什么类型的值,它就是什么类型的变量。本例子中分别注释掉的两段语句就说明了这个问题:Js在运行时既能够将子类变量赋给基类变量(这个特性在C++等语言中正是实现多态的关键),也可以将基类变量赋给子类变量(一般在静态语言中不允许,因为缺少附加信息)。

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]


四、总结
  综合以上分析,js勉强能够算是一种面向对象的语言,因此,也可以将一些软件工程的思想应用到开发中,使得整个项目的架构稳定,逻辑清晰。51js论坛的万常华前辈作出了很大的努力,他将js的面向对象特性设计成一种规则,模仿java的包-类结构,做出了一些由这种规则支撑的常用类库,经过一段时间的努力和完善,已经可以初步进行应用了。

  附记:写这篇文章来源于一个灵感,在学习设计模式的时候,我联想到目前web程序设计中的诸多不规范情况,多数人依然使用传统的过程化结构来控制整个项目,当项目越做越大的时候常有力不从心的感觉。混乱的设计、到处隐藏的bug,这一切注定无法避免么?于是,我尝试用面向对象的思路来重新看待js,并期望以后能够在这个基础上,将一些设计模式应用到web程序设计上来,在界面设计与事务处理分离的前提下,让整个项目的架构趋于合理、稳定。写这篇文章的时候,我并不知道到底我对js了解了多少,也不知道我的理解是否包含了严重的错误,这一切只是一个探索,也希望大家能够赐教,或者给出好的建议。本人是东南大学计算机系大四的学生,碰巧的是,这学期软件体系结构课程老师要求自由选题写一篇论文,花了一个星期时间,希望没有让老师失望,呵呵。
posted on 2006-03-13 16:33 汪杰 阅读(210) 评论(0)  编辑 收藏 引用 所属分类: javascript
只有注册用户登录后才能发表评论。

<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 468991
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜