浏览 1434 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2007-12-20
Ext.extend使用闭包的方式实现,其中综合了属性拷贝与prototype方式的模拟继承技术。
只是在看代码时有几个疑问,还请大侠们指教下。 首先看,if(typeof sp == 'object')代码块。根据ext的文档,继承一般这么用: Ext.extend(SubClass,SuperClass,{}),也就是说一般第二个参数是个function(父类构造函数)类型。 但是如果我们给第二个参数传递object,如Ext.extend{SubClass,{fun:function(){}}),那么该if 分支就会走到。 这个分支走到底时候发生了什么呢? 从 overrides = sp; 上看,第三个参数首先就被抛弃掉了,因为overrides引用已经被直接修改为sp对象了。 overrides保存了sp的引用后,sp通过sp = sb;被修改为sb的引用。看不清楚的是,第三个句子:
sb = function(){sp.apply(this, arguments);};
sb自己被重新赋予与一个新定义的函数,这个构造函数的实现由点奇怪。为什么呢?既然sp通过sp=sb语句已经被修改为sb了那么,这个函数定义就应该如下面的句子等效: sb = function(){sb.apply(this, arguments);}
sb 调用apply自己,有什么用呢? 或者直接告诉我作者这个分支的可能意图是什么:)?多谢 除了鉴别第二个参数,可能的抛弃第三个参数外... ============================= extend : function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; return function(sb, sp, overrides){ if(typeof sp == 'object'){ overrides = sp; sp = sb; sb = function(){sp.apply(this, arguments);}; } var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; if(spp.constructor == Object.prototype.constructor){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.override = io; Ext.override(sb, overrides); return sb; }; }(), 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-12-20
//找到资料了... ...分享
阅读Ext 学习Javascript(二)Core/Ext.extend 从继承说起 一般的,如果我们定义一个类,会定义一个function对象,然后将公用方法写到其原型上,例如: var Tiger = function(){} Tiger.prototype.Hunting = function(){} 但是要建立一个完善的框架或者类库,没有继承帮忙,组织代码将是一件非常辛苦且难以管理的工作。Js中的类是function对象,实现继承,主要要将子类的原型设置为父类的一个实例(这样子类就用有了父类原型的所有成员),并重新将子类原型的构造器设置为子类自己。如以下代码所示: function Animal(){} function Tiger(){} Tiger.prototype = new Animal() Tiger.prototype.constructor = Tiger 实现继承并不难,将上面的Animal和Tiger参数化封装为一个方法就可以实现(当然实际应用中就要复制一些了),代码如下: function Extend(subFn, superFn){ subFn.prototype = new superFn() subFn.prototype.constructor = subFn } Ext作为一个优秀的框架,当然也少不了继承的实现。如前一篇文章所谈到的,现在让我们一行行代码理解Ext.extend extend : function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; return function(sb, sp, overrides){ if(typeof sp == 'object'){ overrides = sp; sp = sb; sb = function(){sp.apply(this, arguments);}; } var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; if(spp.constructor == Object.prototype.constructor){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.override = io; Ext.override(sb, overrides); return sb; }; }() 本来只有两行代码就可以实现的继承变成了近30行,Ext都做了什么呢?通常情况下只传入两个类型的话(subFn和superFn),上面的代码将简化为 extend : function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; return function(sb, sp, overrides){ var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; sb.override = function(o){ Ext.override(sb, o); }; sbp.override = io; Ext.override(sb, overrides); return sb; }; }() 定义一个空函数,将其原型设置为sp的原型spp,其实F就是sp的一个替身,理解的时候可以认为就是sp。将子类sb的原型设置为F的一个实例,然后再将其原型的构造器设置为自己sb,为了方便找到父类sp,在子类sb上添加了一个superclass属性为父类sp的原型spp。为了方便扩展属性,在子类sb上添加了属性重写的override方法,也在其原型上添加了override方法(这样其所有实例对象就可以从一个对象重写现有属性了)。 到这里算是对继承有了一些了解(不到位的地方在以后的阅读中继续加强)。好了,有了继承的支持,我们就可以加速类型的扩展了 |
|
| 返回顶楼 | |
|
最后更新时间:2007-12-20
支持楼主,要多些这种对源码的讲解,我们会对ext理解的更深刻
|
|
| 返回顶楼 | |
|
最后更新时间:2007-12-21
使用Ext.extend可以添加或者override父类成员,那么有没有什么手段可以隐藏父类成员呢?
|
|
| 返回顶楼 | |
|
最后更新时间:2007-12-26
sb = function(){sp.apply(this, arguments);};
这行还是没解释 |
|
| 返回顶楼 | |
|
最后更新时间:2007-12-27
等下到官方论坛上去问下... ...
是否有什么特殊的考虑 |
|
| 返回顶楼 | |
|
最后更新时间:2008-01-10
参看这个帖子http://www.javaeye.com/topic/149866
的最后一个关于extend两个参数与三个参数使用方式的回复 明白了extend两个参数和三个参数的使用方式,就会知道如果 没有下面这行代码 <STRONG>sb = function(){sb.apply(this, arguments);}</STRONG> 那么sb在两个参数的使用的时候 子类本身就会被修改 从而 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, { readRecords : function(o) { // do something } }); 这样的使用方式就不会成立,而且Ext.data.JsonReader本身会被修改掉。 |
|
| 返回顶楼 | |





