转载 Ext.extend用法(ext的继承)

转载Ext.extend用法(ext的继承)收藏

<script type="text/javascript"><!-- function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();} // --></script>

概述

Ext.extendExt的继承机制,这个函数的代码相当难懂。要明白这个函数的代码,首先要知道这个函数如何使用。

使用方式

使用示例

假设有个function名为SuperClass,要实现一个子类,名为MyClass。下面的两种方式都可以实现这个功能。


  1. MyClass=Ext.extend(SuperClass,{/**/});
  2. Ext.extend(MyClass,SuperClass,{/**/});

下面来个具体示例:

  1. vara=function(id){
  2. this.id=id;
  3. }
  4. a.prototype={
  5. tostring:function(){
  6. returnthis.id;
  7. }
  8. };
  9. b=function(id){
  10. b.superclass.constructor.call(this,id);
  11. }
  12. Ext.extend(b,a,{
  13. tostring:function(){
  14. returnString.format("b:{0}",this.id);
  15. }
  16. });
  17. //测试一下
  18. varobj1=newa("obj1");
  19. alert(obj1.tostring());
  20. varobj2=newb("obj2");
  21. alert(obj2.tostring());
或者下面的代码,可以得到同样的效果:

  1. vara=function(id){
  2. this.id=id;
  3. }
  4. a.prototype={
  5. tostring:function(){
  6. returnthis.id;
  7. }
  8. };
  9. b=Ext.extend(a,{
  10. tostring:function(){
  11. returnString.format("b:{0}",this.id);
  12. }
  13. });
  14. //测试一下
  15. varobj1=newa("obj1");
  16. alert(obj1.tostring());
  17. varobj2=newb("obj2");
  18. alert(obj2.tostring());

一个错误例子

下面看个示例:

  1. BaseClass=function(){
  2. this.f1=function(){
  3. alert("f1inbase");
  4. }
  5. this.f2=function(){
  6. alert("f2inbase");
  7. }
  8. }
  9. ChildClass=function(){
  10. ChildClass.superclass.constructor.call(this);
  11. }
  12. Ext.extend(ChildClass,BaseClass,{
  13. f1:function(){
  14. alert("f1inchild");
  15. },
  16. f3:function(){
  17. alert("f3inchild");
  18. }
  19. });
  20. varb=newChildClass();
  21. b.f1();
  22. b.f2();
  23. b.f3();

可以去执行一下,可以发现f1的执行结果仍然是"f1 in base"。并没有真正的达到override的效果。


  1. Ext.extendputsthepropertiesspecifiedinthe3rdargumentintothesubclass'sprototype

也就是说:第三个参数里面的函数被放置在了子类的prototype中。

而在ChildClass.superclass.constructor.call(this);这句上,BaseClassf1成了ChildClass的变量,而不是ChildClass.prototype。通过对JavaScript的原型继承的了解,可以知道,实例变量的优先级是高于prototype的,所以上面的这个代码是达不到override的功能的。

修改的方式如下:

  1. BaseClass=function(){
  2. };
  3. BaseClass.prototype={
  4. f1:function(){
  5. alert("f1inbase");
  6. }
  7. };

代码解读

JavaScript中的继承实现

先了解一下最简单的继承是如何实现的:

  1. functionExtend(subFn,superFn){
  2. subFn.prototype=newsuperFn()
  3. subFn.prototype.constructor=subFn
  4. }
  5. functionAnimal(){
  6. this.say1=function(){
  7. alert("Animal");
  8. }
  9. }
  10. functionTiger(){
  11. this.say2=function(){
  12. alert("Tiger");
  13. }
  14. }
  15. Extend(Tiger,Animal);
  16. vartiger=newTiger();
  17. tiger.say1();//"Animal"
  18. tiger.say2();//"Tiger"

以看到最简单的继承只做了两件事情,一是把subFnprototype设置为superFn的一个实例,然后设置subFn.prototype.constructorsubFn

Ext.extend的代码

Ext.extend函数中用到了Ext.override,这个函数把第二个参数中的所有对象复制到第一个对象的prototype中。首先贴上Ext.override函数的代码:

  1. Ext.override=function(origclass,overrides){
  2. if(overrides){
  3. varp=origclass.prototype;
  4. for(varmethodinoverrides){
  5. p[method]=overrides[method];
  6. }
  7. }
  8. }

然后贴上Ext.extend的代码:

  1. /**
  2. *继承,并由传递的值决定是否覆盖原对象的属性
  3. *返回的对象中也增加了override()函数,用于覆盖实例的成员
  4. *@param{Object}subclass子类,用于继承(该类继承了父类所有属性,并最终返回该对象)
  5. *@param{Object}superclass父类,被继承
  6. *@param{Object}overrides(该参数可选)一个对象,将它本身携带的属性对子类进行覆盖
  7. *@methodextend
  8. */
  9. functionextend(){
  10. //inlineoverrides
  11. vario=function(o){
  12. for(varmino){
  13. this[m]=o[m];
  14. }
  15. };
  16. returnfunction(sb,sp,overrides){
  17. if(typeofsp=='object'){
  18. overrides=sp;
  19. sp=sb;
  20. sb=function(){sp.apply(this,arguments);};
  21. }
  22. varF=function(){},sbp,spp=sp.prototype;
  23. F.prototype=spp;
  24. sbp=sb.prototype=newF();
  25. sbp.constructor=sb;
  26. sb.superclass=spp;
  27. if(spp.constructor==Object.prototype.constructor){
  28. spp.constructor=sp;
  29. }
  30. sb.override=function(o){
  31. Ext.override(sb,o);
  32. };
  33. sbp.override=io;
  34. Ext.override(sb,overrides);
  35. returnsb;
  36. };
  37. }();

代码中进行了太多的简写,看起来不是特别方便,把代码中的简写补全,代码如下:

  1. functionextend(){
  2. //inlineoverrides
  3. varinlineOverride=function(o){
  4. for(varmino){
  5. this[m]=o[m];
  6. }
  7. };
  8. returnfunction(subFn,superFn,overrides){
  9. if(typeofsuperFn=='object'){
  10. //如果subFn也是对象的话(一般来说subFn这里放的是父类的构造函数),那么第三个参数overrides参数相当于被忽略掉
  11. overrides=superFn;
  12. superFn=subFn;
  13. //subFn重新定义了函数
  14. subFn=function(){
  15. superFn.apply(this,arguments);
  16. };
  17. }
  18. varF=function(){
  19. },subFnPrototype,superFnPrototype=superFn.prototype;
  20. F.prototype=superFnPrototype;
  21. subFnPrototype=subFn.prototype=newF();
  22. subFnPrototype.constructor=subFn;
  23. subFn.superclass=superFnPrototype;
  24. if(superFnPrototype.constructor==Object.prototype.constructor){
  25. superFnPrototype.constructor=superFn;
  26. }
  27. subFn.override=function(obj){
  28. Ext.override(subFn,obj);
  29. };
  30. subFnPrototype.override=inlineOverride;
  31. Ext.override(subFn,overrides);
  32. returnsubFn;
  33. };
  34. };

补全以后也不是特别容易明白,那么我们就把这个代码分开,分为2个参数和3个参数。

两个参数的Ext.extend代码

首先把代码改写成两个参数的。

  1. //两个参数的时候的代码,注意第二个参数必须为object
  2. functionextend(){
  3. //inlineoverrides
  4. varinlineOverride=function(o){
  5. for(varmino){
  6. this[m]=o[m];
  7. }
  8. };
  9. returnfunction(superFn,overrides){
  10. varsubFn=function(){
  11. superFn.apply(this,arguments);
  12. };
  13. varF=function(){
  14. },subFnPrototype,superFnPrototype=superFn.prototype;
  15. F.prototype=superFnPrototype;
  16. //注意下面两句就是上面最简单的继承实现。
  17. subFnPrototype=subFn.prototype=newF();
  18. subFnPrototype.constructor=subFn;
  19. //添加了superclass属性指向superFn的Prototype
  20. subFn.superclass=superFnPrototype;
  21. //为subFn和subFnPrototype添加override函数
  22. subFn.override=function(obj){
  23. Ext.override(subFn,obj);
  24. };
  25. subFnPrototype.override=inlineOverride;
  26. //覆盖掉子类prototype中的属性
  27. Ext.override(subFn,overrides);
  28. returnsubFn;
  29. };
  30. };

从注释中可以看到,做的工作很简单,只是定义一个subFn函数,这个函数中会调用superFn函数。定义了subFn以后,就使用上面的最简单的继承方式实现继承。然后为subFnsubFnprototype添加了一个override函数。最后的Ext.override(subFn, overrides);overrides中的函数写入subFnprototype中。

三个参数的Ext.extend代码

下面我们把函数改写为只处理3个参数的,改写后的代码如下:

  1. //三个参数时的代码
  2. functionextend(){
  3. //inlineoverrides
  4. varinlineOverride=function(o){
  5. for(varmino){
  6. this[m]=o[m];
  7. }
  8. };
  9. returnfunction(subFn,superFn,overrides){
  10. varF=function(){
  11. },subFnPrototype,superFnPrototype=superFn.prototype;
  12. F.prototype=superFnPrototype;
  13. //注意下面两句就是上面最简单的继承实现。
  14. subFnPrototype=subFn.prototype=newF();
  15. subFnPrototype.constructor=subFn;
  16. //添加了superclass属性指向superFn的Prototype
  17. subFn.superclass=superFnPrototype;
  18. //为subFn和subFnPrototype添加override函数
  19. subFn.override=function(obj){
  20. Ext.override(subFn,obj);
  21. };
  22. subFnPrototype.override=inlineOverride;
  23. //覆盖掉子类prototype中的属性
  24. Ext.override(subFn,overrides);
  25. returnsubFn;
  26. };
  27. };

过程与两个参数的时候相差无几,只是两个参数的时候,subFn时重新定义的一个function,而三个参数的时候,这个步骤就省略了。

总结及说明

这样大家就对这个函数很明白了吧,也可以知道Ext.extend的继承只会覆写构造函数prototype中的对象,使用的时候需要多加注意。

注意下面一段代码

  1. if(superFnPrototype.constructor==Object.prototype.constructor){
  2. superFnPrototype.constructor=superFn;
  3. }

这段代码我在改写的Ext.extend中省略掉了。原因在于我尝试了多次,发现参数为两个参数的时候,只有第一个参数为Object对象或者为3个参数的时候,第二个参数为Object才会进入此段代码。

但是发现superFn也时function Object(){},在IEFF下都是如此。那么我就不是很清楚这段代码到底是什么用的了,若有清楚的,告诉一声,哈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值