`

【Extjs学习一】Extjs2继承函数简单分析及疑问

阅读更多
Ext = {version: '2.0'};

 

        /**
         * 继承,并由传递的值决定是否覆盖原对象的属性
         * 返回的对象中也增加了override()函数,用于覆盖实例的成员
         * @param {Object} subclass 子类,用于继承(该类继承了父类所有属性,并最终返回该对象)
         * @param {Object} superclass 父类,被继承
         * @param {Object} overrides (该参数可选) 一个对象,将它本身携带的属性对子类进行覆盖
         * @method 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;//@1
                F.prototype = spp;//原型链继承基本原理的实现只有这三行的部分代码 其他代码都具有技巧性,都是为了达到一定的效果或者避免一些缺点。
                sbp = sb.prototype = new F();//用空函数 可以避免子类或得父类的实例变量 即直接定义在构造函数中的变量 避免浪费,也正是这个原因,我们需要的constructor superclass要采用下面的处理。
                sbp.constructor=sb;//@2 设置子函数的构造函数 为什么不是sb.constructor=sb呢,请了解javascript 关于constructor的知识,主意是作为类来使用的,constructor属性为类的实例提供方便,参考@1
                sb.superclass=spp;//这里是apply sbp的superclass 这样做不仅sb的实例可以得到superclass sb本身也可以得到
                if(spp.constructor == Object.prototype.constructor){//
                    spp.constructor=sp;//父类sp到达继承链的顶级 如{} 等 得指定他们的spp的构造函数 方便所有继承系列中的子类能正确调用到父类的构造函数 避免调用到Object.prototype.constructor
                }
                sb.override = function(o){//@3
                    Ext.override(sb, o);
                };//给子类本身加上override方法 方便sb的重载、重写实现
                sbp.override = io;

//给sb的子类提供好override方法//@4  @3@4可对比@2并思考区别, 为什么不写成sbp.override=function(o){Ext.apply(this,o);} ?














                Ext.override(sb, overrides);//override属性 类级别的 区别前面 只有一个参数的 是实例级别的 没啥好说的吧?
                return sb;
            };
        }(),



一、关于F的用法
Js中的类是function对象,实现原型链继承,主要要将子类的原型设置为父类的一个实例(这样子类就用有了父类原型的所有成员),并重新将子类原型的构造器设置为子类自己。
如以下代码所示:

 

function Animal(){}
function Tiger(){}
Tiger.prototype = new Animal()//@1
Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。

 


问题(一):为什么不采用如下这种方式呢?

 

function Animal(){}
function Tiger(){}
Tiger.prototype =Animal.prototype//因为@1
Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。

 


原因:为了避免对sb原型对象的操作,联动影响sp的原型对象。
问题(二):那么Ext.extent为什么要使用F这个空函数呢?
原因:用空函数,可以避免子类获得父类的实例变量 即直接定义在构造函数中的变量 避免浪费。

二、sb的原型属性是否保留

当typeof sp == "function"时,sb的原型将被替换,不保留任何原型属性,sb的superclass指向sp的原型对象;
3,当typeof sp == "object"时,sb的原型属性将被保留,sb的superclass指向自己的原型对象,效果略等同于override, 区别在于指定了superclass


三、其他要点
(一)apply,applyIf主要用于typeof == "object"时的对象操作
(二)override,extend主要用于typeof == "function"时的对象原型操作
(三)一般有两种方式使用ext.extend,建议尽量使用第二种,省去了config自己操作的麻烦。Component.js

    第一种:

    /* // protected
     * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
     */
// Traditional constructor:
Ext.Foo = function(config){
	// call superclass constructor:
    Ext.Foo.superclass.constructor.call(this, config);

    this.addEvents({
		// add events
    });
};
Ext.extend(Ext.Foo, Ext.Bar, {
   // class body
}







































    第二种:

// initComponent replaces the constructor:
Ext.Foo = Ext.extend(Ext.Bar, {
    initComponent : function(){
		// call superclass initComponent
        Ext.Container.superclass.initComponent.call(this);

        this.addEvents({
            // add events
        });
    }
}








































四、js基础知识总结:

typeof 运算符

返回一个用来表示表达式的数据类型的字符串。

typeof [( )expression [] ] ;

expression 参数是需要查找类型信息的任意表达式

 

http://book.csdn.net/bookfiles/110/1001103362.shtml

ps:js设计的一个小错误,请主意。

 

原始类型、引用类型 :http://book.csdn.net/bookfiles/110/1001103364.shtml

这本书可以看看:http://book.csdn.net/bookfiles/110/#c1

说明

typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: "number," "string," "boolean," "object," "function," 和 "undefined."

typeof 语法中的圆括号是可选项。

 


typeof的结果只有可能是'number','string','boolean','function','object','undefined'。new 生成的对象typeof为object。
instanceof右边一定是Number,String,Boolean,Function,Object,自定义函数对象。
.constructor的结果也只可能是Number,String,Boolean,Function,Object,自定义函数对象。
且Number,String,Boolean,Function,Object,自定义函数对象,她们的.constructor都是Function,typeof 她们 == 'function'。

掌握javascript的prototype链原理及{}.prototype为null//undifined 但是请主意Object.prototype为“object” 因为typeof Object 为"function",由此可见所以可以使用new的关键字或自定义函数, 如

new Number (),new String (),new Boolean (),new Function (),new Function (),他们都是函数类型。

 

五、使用extjs的一点经验

(一)充分理解继承。

(二)尽量照抄例子,从简单到复杂地进行修改,直到得到你需要的界面效果。

(三)碰到问题,快速使用google codesearch等搜索引擎。

(四)尽可能少的使用ext.get 和ext.getcmp,因为你写的类可能要再某些地方复用,避免id冲突

(后续补充中...)

 

六、一些疑问

(一)if(spp.constructor == Object.prototype.constructor){//   不是很理解,期待有人点拨一下

 

答:主要是为了解决sp为object时的继承问题 如 AB = Ext.extend(sb,Object,overrides )

 

 

(二)sbp.override = io; 为什么要使用io这个函数,类色的函数不是本来就有了嘛 如Ext.apply 

 

答:的确没有

Ext.apply = function(o, c, defaults){
    if(defaults){
        // no "this" reference for friendly out of scope calls
        Ext.apply(o, defaults);
    }
    if(o && c && typeof c == 'object'){
        for(var p in c){
            o[p] = c[p];
        }
    }
    return o;
};

 有

typeof c == 'object'

  这个限制,

applyif 虽然没这个限制,但是该函数的目的是没有的属性才会增加。

        applyIf : function(o, c){
            if(o && c){
                for(var p in c){
                    if(typeof o[p] == "undefined"){ o[p] = c[p]; }
                }
            }
            return o;
        },

 

override 是针对object.prototype的 所以只能这里写一个了。

        override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;
                for(var method in overrides){
                    p[method] = overrides[method];
                }
            }
        },

 

 (三)a.superclass.constructor是c而访问不到b

                sb.superclass=spp;
                if(spp.constructor == Object.prototype.constructor){
                    spp.constructor=sp;
                }

换成
  sb.superclass=sp;
岂不是更好?

答:而且ext用的是原型链继承 subclass就是通过prototype的技巧性处理来继承superclass的 这本身是一个逐级向上的递归过程
所以指定superclass指定到superclass的prototype比较合理,而且以后调用也方便 只需要subclass.superclass.method.call
如果像你那样指定的话就需要subclass.superclass.prototype.method.call  反而更复杂了 。

subclass.superclass.call(this) 的方式没有subclass.superclass.constructor.call(this)的方式直观

而且构造函数constructor我感觉也是显示调用比较好,风格比较一致,而且少点潜规则也更容易看懂吧,没必要学java的那种方式,
而且如果superclass没有构造函数的话 按照ext的方式会逐级向更上层的父类调用,直到最顶端。
见:http://bbs.51js.com/viewthread.php?tid=72688&page=1&extra=#pid556697

 

 

八、相关链接

http://zhuaxia.com/pre_channel/4873283

http://bbs.51js.com/viewthread.php?tid=72688&page=1&extra=#pid556697

http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm

http://www.google.cn/search?complete=1&hl=zh-CN&newwindow=1&rlz=1T4GGLS_zh-CNCN276CN276&q=Ext.extend&meta=&aq=f

http://hi.baidu.com/pmzcn/blog/item/92a05fafbe8187f8faed5057.html

 

 

 

 

 

分享到:
评论
10 楼 jianfeng008cn 2008-06-17  
fins 写道
我说的是第一个问题 不是第二个空函数F的问题

我说了啊, 这些问题的提出都是围绕“ ext的继承为什么要这么写”
构造函数的this.xx在ext的继承方案中就是要避免的。
我不可能说第一个问题是为了“得到”, 第二个问题用空函数是为了“避免得到”
这样来分析吧。
所以第一个问题的着眼点是这种方式带来的副作用是“prototype联动问题”,
而采用new animal() 是可以得到this.xxx,但是这在ext的解决方案里本身是要解决的问题,而不是要达到的效果。
之所以这样分析是用了孤立的方法来各个击破各个可疑之点,从而达到能够全面分析理解各种组合情况的效果
没疑问了吧?
9 楼 sp42 2008-06-16  
我搞错了,可以支持inline constructor的原因是:
sb = [b]overrides.constructor != oc ? overrides.constructor[/b] : function(){sp.apply(this, arguments);};//第十四行

8 楼 sp42 2008-06-11  
空函数是经典的闭包应用,用来解决继承的问题了 呵呵,

至于 "spp.constructor == Object.prototype.constructor",
突然想起ext的OO最近支持constructor关键字的重写了:

DeepCMS.client.layout.Menu = obj.extend(UI.TabPanel, {
	//@override
	constructor : function(){
		var config  =  {
            tabPosition     : 'bottom'
            ,title          : 'DeepCMS'
            ,region         : 'west'
            ,deferredRender : false
            ,border         : false
            ,collapsible    : true
            ,activeTab      : 1
            ,width          : 155
            ,items: [
	             new OA.client.defaultPage.sessionProfile({title: '个人信息'})
	            ,new OA.client.bigButtonArea()
            ]
        };
		DeepCMS.client.layout.Menu.superclass.constructor.call(this, config);
	}
});

注: obj = UI = Ext;
不知会不会跟这个有关系呢?呵呵
7 楼 fins 2008-06-11  
我说的是第一个问题 不是第二个空函数F的问题
6 楼 jianfeng008cn 2008-06-11  
fins 写道
引用

问题(一):为什么不采用如下这种方式呢?


这个的解释不对吧
真正目的是 为了获得在“构造函数里”通过 this.XXX 方式定义的属性吧


用new F() 也是得不到的 ,所以需要显式调用 superclass.constructor.call ,
空函数就是为了避免得到superclass 构造函数 中定义 的 this.xxx 这种属性啊 ,如果需要则superclass.constructor.call要使用到了.

这个问题的提出也是围绕ext.extend的解决方案的。
5 楼 fins 2008-06-11  
引用

问题(一):为什么不采用如下这种方式呢?


这个的解释不对吧
真正目的是 为了获得在“构造函数里”通过 this.XXX 方式定义的属性吧
4 楼 cscs31 2008-06-11  
好专业啊,厉害厉害!佩服佩服
3 楼 jianfeng008cn 2008-06-11  
sp42 写道
spp.constructor == Object.prototype.constructor

这个我也不明白,似乎是为解决继承链不能超过两次?
见:
引用
I've found that its easy to build a JS OOP idiom to support one level of inheritance that fails with two more more levels of inheritiance.

http://kevlindev.com/tutorials/javascript/inheritance/index.htm

http://sp42.iteye.com/admin/blogs/201143

望引证。



我去看了 不是这个原因 不能超过两次 是通过指定subclass的superclass 和 construtor来实现的
2 楼 sp42 2008-06-11  
spp.constructor == Object.prototype.constructor

这个我也不明白,似乎是为解决继承链不能超过两次?
见:
引用
I've found that its easy to build a JS OOP idiom to support one level of inheritance that fails with two more more levels of inheritiance.

http://kevlindev.com/tutorials/javascript/inheritance/index.htm

http://sp42.iteye.com/admin/blogs/201143

望引证。
1 楼 jianfeng008cn 2008-06-10  
我刚发的,有研究的朋友请指点指点

相关推荐

    EXtJS学习 EXtJS学习

    EXTJS 学习:深入理解 `Ext.extend` 及其在继承中的陷阱 EXTJS 是一个强大的 JavaScript 框架,用于构建富客户端应用程序。它提供了丰富的组件库和强大的数据绑定机制。在 EXTJS 中,`Ext.extend` 是核心的继承机制...

    ExtJS4中文教程2 开发笔记 chm

    ExtJS4学习笔记(一)---window的创建 ExtJS4学习笔记(七)---带搜索的Grid(SearchGrid) ExtJS4学习笔记(三)---VBox的使用 ExtJS4学习笔记(九)---ExtJS4 EditGrid(可编辑的Grid) ExtJS4学习笔记(二)---HBox的使用 ...

    EXTJS学习文档 适合初学者

    页面加载完毕后,EXTJS会执行`Ext.onReady`函数中指定的代码,这是EXTJS应用的一个关键启动点。例如: ```javascript Ext.onReady(function() { alert("ExtJS库已加载!"); }); ``` 这里,`Ext.onReady`函数...

    无废话ExtJs 系列教程十八[继承:Extend]

    在"无废话ExtJS系列教程十八[继承:Extend]"中,我们主要关注的是ExtJS中的类继承机制,这是一个核心特性,它允许开发者创建可复用和可扩展的组件结构。在JavaScript中,继承是通过原型链实现的,而在ExtJS中,它被...

    轻松搞定Extjs 带目录

    Extjs的`Ext.util.Format`类提供了一组内置的格式化函数,用于文本、日期和数字的格式化。还可以自定义格式化函数,或者通过`XTemplate`进一步自定义内容。 #### 8. 组件结构 Extjs的组件结构复杂且功能强大,包括...

    Extjs2.x主题

    ExtJS是一个广泛使用的JavaScript库,专门用于构建富客户端应用程序。在2.x版本中,它提供了丰富的用户界面组件和强大的数据管理功能。主题是ExtJS应用的外观和感觉,定义了控件的颜色、字体、布局样式等。下面我们...

    extJS 一些简单实例

    ExtJS 是一个强大的JavaScript库,专门用于构建富客户端的Web应用程序。它提供了丰富的用户界面组件、数据绑定机制和可扩展的架构,使开发者能够创建功能丰富的、交互式的Web应用。在"extJS 一些简单实例"这个主题中...

    EXT 中文手册 搭配ExtJs2.2实例更快将ExtJs入手

    这可能包括如何使用JavaScript对象、函数、数组等基本概念,以及如何利用JavaScript的原型继承机制来扩展ExtJs的组件。此外,手册也可能涉及Ajax通信、DOM操作等JavaScript高级特性,这些都是ExtJs开发中不可或缺的...

    extjs简单例子

    这个“extjs简单例子”教程集合,显然旨在帮助初学者快速上手并理解ExtJS的基本概念和功能。下面,我们将详细探讨这些文件所涵盖的知识点。 1. **《TutorialIntroduction to Ext 2.0 (Chinese)》** 这个文档可能...

    EXTJS入门教程(非常详细)

    EXTJS是一个基于JavaScript的框架,它主要用于开发具有丰富用户界面的Web应用程序。该框架使用了JavaScript、HTML和CSS,通过使用组件驱动的方式来构建用户界面。在EXTJS入门教程中,我们将会了解到EXTJS的核心概念...

    ExtJS如何自定义图片按钮组件

    4.此组件继承的是Ext.Panel,而不是Button,所以此组件并没有所有Ext.Button的功能但是拥有所有Ext.Panel功能并新增了点击事件(使用规范请参照js附件的onReady函数)。本人现正在研究如何重写Ext.Button,如有所收获,...

    ExtJS入门教程(超级详细)

    此外,入门教程中还会介绍如何创建一个简单的ExtJS示例程序,例如显示一个弹出窗口或一个面板(ExtPanel)。ExtJS通过一套丰富的组件来构建用户界面,这些组件可以直接在项目中使用,并可以进行适当的定制以适应不同...

    Extjs源码之--Ext事件机制/继承关系

    在EXTJS这个强大的JavaScript框架中,事件机制是其核心组件之一,它允许组件之间进行通信和交互。在“Extjs源码之--Ext事件机制/继承关系”中,我们将深入探讨EXTJS如何处理事件以及其类层次结构。EXTJS的事件处理...

    ExtJS中文手册.pdf

    - **文件类型**:通常情况下,下载文件包括最新的稳定版本,同时也包含示例文件夹(example文件夹),这是一个非常好的学习资源。 #### 3. Element:Ext的核心 - **核心组件**:Element是ExtJS的核心组成部分之一,...

    EXTJS学习笔记

    ### EXTJS学习笔记 #### 一、EXTJS基础概念与命名空间管理 **EXTJS** 是一款基于JavaScript的开源框架,主要用于开发复杂的企业级Web应用。它的设计目标是提高前端开发效率并简化复杂的用户界面(UI)开发过程。在...

    Extjs4.0一些常见入门学习范例带注释详解

    以上就是关于ExtJS 4.0的一些入门学习范例的详解。掌握这些基础概念将有助于你构建复杂的用户界面和数据驱动的应用程序。在实际开发中,你还可以探索更多高级特性,如布局管理、组件通信、数据存储、远程数据同步等...

Global site tag (gtag.js) - Google Analytics