`
driftcloudy
  • 浏览: 132224 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

DOJO中的面向对象__第三章补充:关于preamble、postscript以及chain

    博客分类:
  • Dojo
阅读更多

  这是dojo.declare中的三个极度蛋疼的功能,在对多继承的实质有所了解之后,才会加深对这三个功能的认识,所以放到最后说。这里就不谈它们的实现原理了,第四章中也许会描述到= =!

 

  如果觉得运行constructor前后缺少了些什么,那么preamble、postscript可以很好的帮助我们进行弥补。根据我时间不长的开发经验,还想不出什么情况下需要这种操作来弥补。如果在类型的定义中包含了preamble方法,那么在这个类型的构造函数被调用之前,会首先执行一次preamble。同样如果定义了postscript方法,那么该类型的构造函数被调用之后,也会自动执行一遍postscript。下面是一个简单的例子:

dojo.declare('A',null,{
	preamble:function(){ console.log('A'); },	
	constructor:function(){ console.log('AA'); },
	postscript:function(){ console.log('AAA'); }
});
var a= new A();
/*输出:
A
AA
AAA
*/
 

  至于preamble和postscript方法究竟是如何被调用的,第四章中有解释,暂时不需要关注,可以认为这是Dojo提供好的机制。来个复杂一些的例子:

dojo.declare('A',null,{
	preamble:function(){ console.log('A'); },	
	constructor:function(){ console.log('AA'); },
	postscript:function(){ console.log('AAA'); }
});
dojo.declare('B',A,{	
	preamble:function(){ console.log('B'); },	
	constructor:function(){ console.log('BB'); },
	postscript:function(){ console.log('BBB'); }
});
dojo.declare('C',B,{	
	preamble:function(){ console.log('C'); },	
	constructor:function(){ console.log('CC'); },
	postscript:function(){ console.log('CCC'); }
});
var c= new C();
/* 输出:
C
B
A
AA
BB
CC
CCC
*/
 

  从输出的结果来看,我们可以挖掘出一些有意思的事情。在这种拥有继承的情况下,父类中postscript方法是不会被自动调用到的。上述例子的准确函数执行顺序是:

写道
1. C.preamble
2. B.preamble
3. A.preamble
4. A.constructor
5. B.constructor
6. C.constructor
7. C.postscript
 

  至于为什么不会调用到A和B的postscript方法,从Dojo的源码实现上讲是因为这里所调用的父类型的constructor并没有去执行postscript方法。换个角度说,这里调用父类型的constructor函数完成的构造过程,与我们直接通过new来调用的父类型发生的构造,是两回事。归纳来说,对类型L(A)= AA1A2A3…AN使用new进行实例化时,默认的执行顺序是:

写道
A.preamble-> A1.preamble-> A2.preamble ... AN.preamble->
AN.constructor-> AN-1.constructor ... A.constructor->
A.postscript
 

  在Dojo1.4之后的版本中,preamble已经被标记为deprecated函数,不过postscript并没有被列入deprecated。chain提供了自动执行父类中函数的功能。默认情况下,只有父类的构造函数是会被自动调用的,并且总是先于子类的构造函数执行。只有在一些特殊情况下,我们会需要让其他的函数也能够像构造函数一样,自动执行,免去我们手工调用的麻烦。举例来说,如果创建的类型包含了destroy函数,该函数会进行一些垃圾回收方面的工作,我们肯定希望destroy函数完成后也会自动去执行一下父类中的destroy。


  下面的例子定义了一条destroy函数组成的chain。其中的允许我们来设置函数的执行顺序,这里指定的是before顺序,也就是说子类的函数会先于父类的函数执行,所以子类的destroy先运行。

dojo.declare('A',null,{	
	constructor:function(){ console.log('A'); },
	destroy:function(){console.log('AA');}
});
dojo.declare('B',A,{	 
	constructor:function(){ console.log('B'); },
	destroy:function(){console.log('BB');}
});

dojo.declare('C',B,{	
	"-chains-": {
    		destroy: "before"
  	},
	constructor:function(){ console.log('C'); },
	destroy:function(){console.log('CC');}
});

var c= new C();
c.destroy();
/*输出:
A
B
C
CC
BB
AA
*/
 

有两点值得注意:


  第一点是"-chains-"语句所处的位置,上例中放在了C类型的定义中。如果放在A或者B类中,执行c.destroy()的效果还是一样的。事实上,只要把chain声明放在继承链条中的任何一个类型定义里,都可以达到串连所有同名函数的效果。对于复杂的多重继承结构也是这样的,因为他们实质上最终还是一条单继承结构。


  第二点是chain中允许我们声明三种类型的顺序,他们能够产生效果的对象不同。字面上,我们能够使用的是after\before\manual这三个顺序,他们分别代表了在父类函数执行之后执行、在父类函数执行之前执行、手动调用。对于非构造函数,设置manual是没有意义的,如果不是after顺序,会被一概视为before。而对于构造函数,设置before是没有意义的,因为父类的构造函数要么manual手动调用,要么一定会在子类的构造函数之前执行。

dojo.declare('A',null,{	
 	"-chains-": {
    		constructor: "before",	//没有作用,非‘manual’即被视为‘after’
    		foo: "manual"				//没有作用,非‘after’即被视为‘before’
  	},
	constructor:function(){ console.log('A'); },
	foo:function(){console.log('AA');}
});
dojo.declare('B',A,{	
	constructor:function(){ console.log('B'); },
	foo:function(){console.log('BB');}
});
dojo.declare('C',B,{	
	constructor:function(){ console.log('C'); },
	foo:function(){console.log('CC');}
});
var c= new C();
c.destroy();
/*输出:
A
B
C
CC
BB
AA
*/
 

  最后来看一个针对构造函数设置manual的例子。

dojo.declare('A',null,{
	"-chains-": { constructor: "manual" },
	constructor:function(){ console.log('A'); }
});
dojo.declare('B',A,{		
	constructor:function(){ console.log('B'); }
});
dojo.declare('C',B,{	
	constructor:function(){		
		this.inherited(arguments); //设置为manual后,只能手动调用父类函数
		console.log('C'); 
	}
});
var c= new C();
/*输出:
B
C
*/
 

  从这个例子可以看出,在设置了manual后,如果不手动去调用父类的构造函数,那么父类的构造函数是不会执行的,因此这里就不会打印A,根据第二章中的描述,手动调用可以使用inherited方法。

 

  PS,之前我以为preamble、postscript以及chain会在dijit中被较多使用到,但根据在Dojo1.5源码中的搜索,很不幸,只有postscript在dijit中被使用过,至于preamble和chain基本上在整个Dojo的实现代码中都没有,只有在test的代码里出现过两三次。可见这些功能偏门 到什么程度。我觉得API提供的原则应该是简单易用 ,而Dojo的接口往往体现着庞大复杂精深,我想这可能也是很多web fronter不愿意花成本去学习去使用的Dojo的原因吧。其实作为开发者来说,Dojo用熟了也并没有感觉太复杂,你甚至会为它的细致周全感到震撼,但是对于初学者来说,或者是那些急于上手某个Ajax框架进行开发的人,Dojo的确不是一个好的选择。

0
0
分享到:
评论

相关推荐

    dojo_part001_001_001

    dojo_part001_001_001dojo_part001_001_001dojo_part001_001_001

    dojo_part003_003_003

    dojo_part003_003_003dojo_part003_003_003dojo_part003_003_003

    Dojo-China.zip_chinadojo1688_dojo_dojo 实战_dojo中文网

    《Dojo-China.zip》是关于Dojo工具包的实战指南,源自chinadojo1688,主要针对中文用户,提供了丰富的Dojo编程知识。Dojo是一个强大的JavaScript库,尤其在构建富互联网应用(RIA)时,其功能和性能表现卓越。这个...

    使用_Dojo_的_Ajax_应用开发进阶教程

    JavaScript使用原型链实现面向对象编程中的继承机制。 - **prototype**: 每个函数都有一个 `prototype` 属性,用于指定实例化对象的默认属性和方法。 - **__proto__**: 每个对象都有一个 `__proto__` 属性,指向它...

    Dojo.GUI_v6.zip for pencil

    【Dojo.GUI_v6.zip for pencil】是一款专为Pencil设计的GUI模板资源包,它扩展了Pencil这款优秀的Web原型设计工具的功能和视觉元素。Pencil是一个免费且开源的应用程序,允许用户创建各种交互式原型,适用于网页、...

    DOJO_API_中文参考手册 附加注释实例

    Dojo API中文参考手册是一个面向初学者的指导性文件,它详细介绍了Dojo框架的体系结构、常用包及功能,并通过附加注释实例帮助开发者理解和使用Dojo。以下是根据给定内容整理的知识点: 1. Dojo体系架构分层: - ...

    arcgis-js-v411-api及离线部署总结.rar

    1、把 ini.js与dojo.js中的 HOSTNAME_AND_PATH_TO_JSAPI 改成 baseUrl:"http://localhost/hrp_gis/common_railway/arcgis_js_api/library/4.11/dojo" 2、引用 arcgis_js_api 3、跨域 : 1、停掉ArcGIS Server的...

    dojo学习001_20101122

    dojo学习001_20101122.dojo学习文件

    dojo dojo实例 dojo例子 dojo资料 dojo项目 dojo实战 dojo模块 dojo编程

    3. **dojo/ready**:这个模块用于确保DOM加载完成后再执行指定的函数,它是Dojo中的一个实用工具,常用于页面初始化。 4. **dojo/store**:这是一个数据存储抽象层,提供了一种统一的方式来访问和操作数据,无论...

    使用_Dojo_Mobile_为_iOS_智能终端开发_Native-like_Web_应用

    例如,Dojo Mobile中的Container Widget就是一种管理其他部件如何在不同屏幕尺寸和方向下显示的工具,它能够帮助开发者处理视区变化导致的布局问题。 总之,随着智能手机和移动设备的普及,为这些设备开发Native-...

    Dojo中文手册_IT168文库.pdf

    7. 事件处理:Dojo的事件API支持面向切面编程(AOP),以及主题和事件队列的功能,这为开发者提供了更多的事件处理灵活性。 Dojo的设置和配置是应用开发中的重要步骤,包括选择正确的Dojo版本、动态加载package以及...

    DOJO API 中文参考手册

    3. **DOM操作 (dojo/dom, dojo/dom-geometry, dojo/dom-style)**: 这些模块提供了对DOM元素的广泛操作,包括查找、创建、修改和布局计算。`dojo/dom`用于获取和操作DOM元素,`dojo/dom-geometry`处理元素的几何属性...

    提高基于 Dojo 的 Web 2_0 应用程序的性能

    在开发Web 2.0应用程序时,Dojo作为一个强大的JavaScript库,提供了丰富的功能和组件,帮助开发者构建交互式和高性能的网页应用。然而,随着应用复杂性的增加,性能优化成为了一个不可忽视的话题。本文将深入探讨...

    dojo中文文档-dojo手册

    《dojo中文文档-dojo手册》提供了全面而深入的Dojo框架知识,这是一份非常有价值的资源,对于想要理解和掌握Dojo JavaScript库的开发者来说至关重要。Dojo是一个强大的JavaScript工具包,它提供了丰富的功能,包括...

    coding_dojo_mern_stack:编码Dojo Mern堆栈

    coding_dojo_mern_stack:编码Dojo Mern堆栈

Global site tag (gtag.js) - Google Analytics