DOJO中的面向对象__第二章 Dojo中的类
(一) 利用DOJO.DECLARE声明类
在第一章中讲到,JS提供的是一种基于原型(Prototype)的对象系统。这与JS诞生的初衷有关,在把JS仅仅用作页面脚本时,利用Prototype是一种优势。因为基于原型的对象不仅节约内存,初始化速度快,更重要的是还拥有了原型继承带来的动态特性。但是如果需要在RIA环境下构建丰富的web应用,JS的原型系统又显得不太给力。在继承性方面,原型系统能够让两个对象之间发生继承关系,但需要经过构造器来衔接。在封装性方面,JS的表现很糟糕,除了没有关键字支持,JS实质上也只有‘全局’和‘函数’两种级别的作用域。在多态性方面,由于缺少静态类型检查,JS对象无法准确识别子类或者父类的同名方法,更无法调用父类中已经定义的方法。所以归根结底的说,JS里采用的原型的对象系统并不是完备的面向对象系统。
?
对此,Dojo在面向对象的一些特性方面对JS进行了补充,使得开发者能够尽可能的利用Dojo以一种基于类的面向对象思想来组织构建程序。Dojo中提供了一种简单的类型声明方式——dojo.declare,我们可以用来方便的对类型进行描述。如下所示,dojo.declare的格式很简单:
?
上图揭示了dojo.declare实际处理的做法。在真正创建构造器Foo的过程中,除了constructor方法,其他所有声明的字段、方法都会被放进Foo.prototype中。而constructor方法会被当做Foo函数体来执行。由于this.unshared = { num:1 }是被放在Foo中执行的,所以每个实例都会拥有自己的unshared拷贝,另外shared在prototype中,因此被所有的实例共享。如果对dojo.declare细节感兴趣,可以参考第四章。
?
(四) 调用父类方法在dojo中,一般情况下父类型的constructor(构造函数)总是自动被调用,第二小节的例子已经说明这一点。进一步说,父类型的constructor总是优先于子类型的constructor执行。让父类型的构造函数先于子类型的构造函数执行,采用的是after algorithm,还可以不自动调用父类构造函数,而采用手动调用,这些在第三章中会有具体描述。
function extend(source){safeMixin(this.prototype, source);return this;}?
这里的this是指调用extend的类型。safeMixin会将source对象的属性、方法(构造函数除外)毫无保留的添加到this.prototype对象中。由于发生更改的是prototype的对象,因此extend之后,该类型的每个实例都会拥有新赋予的能力,不管该实例是在extend之前还是之后生成。
?
?
?