面向对象JS开发--封装
2007-11-26 14:15
在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关键字绑定到这个类,调用时使用绑定名字来访问,而不是通过实际名字。
问题的根源是什么?是我们没有一种有效的方式来组织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关键字绑定到这个类,调用时使用绑定名字来访问,而不是通过实际名字。
提示:您可以先修改部分代码再运行
示 例1-2:该例子演示了public和private访问限定的实现。本例子中,我们修改了上个例子中的MyClass类,将其扩充为两个属性和两个方 法。注意到PrivateName的声明,它并没有绑定到这个类,因此只具有局部作用域,生命期仅在本类中,如果在类的方法中调用它的话,是可以正常调用 的(调用的时候不加this关键字)。同理,没有绑定的方法也只能在类的内部调用。因此,js中的public与private限定可以通过这种方式来实 现。
提示:您可以先修改部分代码再运行
在这里,需要注意到一个现象,既然js把类本身作为一个构造函数,它在实例化的时候将逐个执行其中的语句,保留其中的方法定义,一直把整个函数执行完。 因此,本例子中注释掉的writePrivateName();语句如果正常执行,将在MyClass类实例化的时候运行。
示例1-3: 该例子演示了static限定的实现。本例子中,我们将MyClass类修改为带一个普通属性、一个静态属性和两个静态方法的类。这个类可以被实例化,所 能够访问的仅仅是在类中定义的普通属性。当不实例化,通过类名访问的时候,可以访问类中的静态方法和静态属性,静态方法只能访问静态属性。与C++类似, 静态成员的初始化需要在类的外面进行。