`

Extjs2继承函数简单分析及疑问

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

Ext = {version: '2.0'};

Java代码
        /** 
         * 继承,并由传递的值决定是否覆盖原对象的属性 
         * 返回的对象中也增加了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);} ?<SPAN>  
 
 
</SPAN>  
 
 
 
 
 
 
 
 
 
 
 
                Ext.override(sb, overrides);//override属性 类级别的 区别前面 只有一个参数的 是实例级别的 没啥好说的吧?  
                return sb;  
            };  
        }(), 

        /**
         * 继承,并由传递的值决定是否覆盖原对象的属性
         * 返回的对象中也增加了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对象,实现原型链继承,主要要将子类的原型设置为父类的一个实例(这样子类就用有了父类原型的所有成员),并重新将子类原型的构造器设置为子类自己。
如以下代码所示:



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

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


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



Java代码
function Animal(){}  
function Tiger(){}  
Tiger.prototype =Animal.prototype//因为@1 

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

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

    第一种:

Java代码
<SPAN style="FONT-SIZE: medium">    /* // 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  
}</SPAN> 

    /* // 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
}







































    第二种:


Java代码
<SPAN style="FONT-SIZE: medium">// 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  
        });  
    }  
}  
</SPAN> 

// 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



答:的确没有

Js代码
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;  
}; 

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;
}; 有

Js代码
typeof c == 'object' 

typeof c == 'object'  这个限制,

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

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

        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的 所以只能这里写一个了。

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

        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的方式会逐级向更上层的父类调用,直到最顶端。

分享到:
评论

相关推荐

    EXTJS简单MVC实例

    只要将解压的文件直接放置到myeclipse的webroot下面,启动tomcat访问。简单的EXTJS mvc框架,设计 store,model,controller,view,window等等,同时展示了一些基本的点击显示、修改等等操作,需要的同学自行下载

    extjs组建继承结构图

    extjs组建继承结构图 让你了解extjs的整个架构!

    Extjs2.x主题

    下面我们将深入探讨ExtJS 2.x的主题及其相关知识点。 1. **主题的基本概念**: 主题(Theme)是ExtJS应用程序的视觉风格,它定义了UI元素的样式,如按钮、表格、窗口等。通过应用不同的主题,可以改变应用程序的...

    EXTJS2 API

    EXTJS2 API是EXTJS2的核心文档,它详细阐述了EXTJS2框架的各种类、方法、属性和事件,帮助开发者深入理解和使用EXTJS2。 EXTJS2 API文档主要包含以下几个关键知识点: 1. **组件(Components)**:EXTJS2的核心是...

    extJS 一些简单实例

    在"extJS 一些简单实例"这个主题中,我们将探讨ExtJS的基础知识以及如何通过一些简单的示例来理解和运用它。 首先,ExtJS的核心是它的组件模型。这些组件包括按钮、表格、窗口、菜单等,可以构建出复杂的用户界面。...

    extjs 常用函数.rar

    在"extjs 常用函数.rar"这个压缩包中,我们重点关注两个特定的函数:`getCMP()` 和 `getDom()`。这两个函数在ExtJS开发中非常常用,帮助开发者获取组件或DOM元素,以便进行后续的操作和交互。 1. `getCMP()` `...

    ExtJs2相关书籍

    《EXT 中文手册》是ExtJS2的官方文档的中文翻译版,是深入理解和掌握ExtJS2的重要参考资料。手册通常会详细解释每一个类、方法、属性和事件,帮助开发者查找并理解特定功能的实现方式。通过阅读这本手册,开发者可以...

    ExtJS3.0 源码分析与开发实例宝典

    ExtJS3.0 源码分析与开发实例宝典

    ExtJS viewModel继承

    ExtJS6 viewModel继承 viewModel各级控件继承演示,动态改变viewModel 详见文章解释 https://blog.csdn.net/ZYD45/article/details/87867454

    Extjs6 最简单的示例java版

    Extjs6 最简单的示例java版Extjs6 最简单的示例java版Extjs6 最简单的示例java版Extjs6 最简单的示例java版Extjs6 最简单的示例java版Extjs6 最简单的示例java版

    extjs最简单最简单的绑定

    这是一个extjs最简单最简单的绑定,请已经实现从数据库中读出后然后绑定到extjs Grid控件的朋友不要下载了,免得您砸鸡蛋。这是一个.net的事例。仅限于没绑定上的朋友下载。extjs绑定json的时候请注意字符串

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

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

    ExtJs表格grid中文排序函数方法

    ExtJs中文排序函数方法详解 在ExtJs框架中,实现中文排序功能是一件非常重要的事情。今天,我们将详细介绍如何使用ExtJs实现中文排序,特别是使用Ext.data.Store.prototype.createComparator()函数来实现中文排序。...

    ExtJS4中文教程2 开发笔记 chm

    JavaScript对象及继承教程(上) javascript正则表达式(一) javascript正则表达式(二) JavaScript的10种跨域共享方法 JavaScript类型总览 JavaScript获取文本框光标的像素位置 js函数match、exec、test、search、...

    Extjs继承结构图.png

    Extjs 组件继承结构图,亲手整理,可用于Extjs学习时快速理清组件之间的关系

    extjs+s2sh

    在IT行业中,"extjs+s2sh"是一个典型的前端与后端框架的集成案例,它结合了ExtJS、Struts2、Hibernate和Spring这四个关键组件。这些技术的结合为开发人员提供了一套完整的解决方案,用于构建功能丰富的、数据驱动的...

    extJs3升级extjs4方案

    ExtJS3 升级到 ExtJS4 方案 ...可以看到,ExtJS4 使用 Ext.create 函数来创建组件类,这样可以更加方便地创建组件。 ExtJS3 升级到 ExtJS4 需要修改大量代码,需要我们重新学习和适应 ExtJS4 的新特性和变化。

    EXTJS单元格变色、行变色

    2. 在columns配置中,添加renderer函数,以实现单元格变色。 3. 在viewConfig中,添加getRowClass函数,以实现行变色。 4. 在renderer函数和getRowClass函数中,根据cell或record的值来决定背景颜色。 5. 使用CSS来...

    轻松搞定Extjs 带目录

    - **类的定义**: Extjs中的类继承于JavaScript原生类,通过Ext.extend来定义。这是Extjs实现面向对象编程的基础。 - **命名空间**: 命名空间在Extjs中用于组织和管理代码,避免变量和函数名的冲突。 #### 3. Extjs ...

Global site tag (gtag.js) - Google Analytics