详解Extextend的使用方法.docx

上传人:b****3 文档编号:3971327 上传时间:2023-05-06 格式:DOCX 页数:13 大小:18.96KB
下载 相关 举报
详解Extextend的使用方法.docx_第1页
第1页 / 共13页
详解Extextend的使用方法.docx_第2页
第2页 / 共13页
详解Extextend的使用方法.docx_第3页
第3页 / 共13页
详解Extextend的使用方法.docx_第4页
第4页 / 共13页
详解Extextend的使用方法.docx_第5页
第5页 / 共13页
详解Extextend的使用方法.docx_第6页
第6页 / 共13页
详解Extextend的使用方法.docx_第7页
第7页 / 共13页
详解Extextend的使用方法.docx_第8页
第8页 / 共13页
详解Extextend的使用方法.docx_第9页
第9页 / 共13页
详解Extextend的使用方法.docx_第10页
第10页 / 共13页
详解Extextend的使用方法.docx_第11页
第11页 / 共13页
详解Extextend的使用方法.docx_第12页
第12页 / 共13页
详解Extextend的使用方法.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

详解Extextend的使用方法.docx

《详解Extextend的使用方法.docx》由会员分享,可在线阅读,更多相关《详解Extextend的使用方法.docx(13页珍藏版)》请在冰点文库上搜索。

详解Extextend的使用方法.docx

详解Extextend的使用方法

extend (Objectsubclass,Objectsuperclass,[Objectoverrides]:

Object 

第一个参数:

子类 

第二个参数:

父类 

第三个参数:

要覆盖的属性。

 

这里需要强调一下,子类继承下来的是父类中通过superclass.prototype方式定义的属性(包括用此方法定义的函数)。

使用方式

使用示例

假设有个 function 名为 SuperClass ,要实现一个子类,名为 MyClass 。

下面的两种方式都可以实现这个功能。

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

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

 

下面来个具体示例:

var a = function ( id ){

    this . id = id ;

}

a . prototype = {

    tostring :

 function (){

        return this . id ;

    }

};

           

b = function ( id ){

    b . superclass . constructor . call ( this , id );

}

Ext . extend ( b , a , {

    tostring :

 function (){

        return String . format ( "b:

{0}" , this . id );

    }

});

// 测试一下

var obj1 = new a ( "obj1" );

alert ( obj1 . tostring ());

var obj2 = new b ( "obj2" );

alert ( obj2 . tostring ());

或者下面的代码,可以得到同样的效果:

var a = function ( id ){

    this . id = id ;

}

a . prototype = {

    tostring :

 function (){

       return this . id ;

    }

};

 

b = Ext . extend ( a , {

    tostring :

 function (){

       return String . format ( "b:

{0}" , this . id );

    }

});

// 测试一下

var obj1 = new a ( "obj1" );

alert ( obj1 . tostring ());

var obj2 = new b ( "obj2" );

alert ( obj2 . tostring ());

 

一个错误例子

下面看个示例:

BaseClass = function () {

    this . f1 = function () {

        alert ( "f1inbase" );

    }

 

    this . f2 = function () {

        alert ( "f2inbase" );

    }

}

 

ChildClass = function () {

  ChildClass . superclass . constructor . call ( this );

}       

 

Ext . extend ( ChildClass , BaseClass , {

    f1 :

 function () {

        alert ( "f1inchild" );

    },

 

    f3 :

 function () {

        alert ( "f3inchild" );

    }

});

 

var b = new ChildClass ();

b . f1 ();

b . f2 ();

b . f3 ();

 

可以去执行一下,可以发现 f1 的执行结果仍然是 "f1inbase" 。

并没有真正的达到 override 的效果。

 

Ext.extendputsthepropertiesspecifiedinthe3rdargumentintothe subclass's prototype

 

也就是说:

第三个参数里面的函数被放置在了子类的 prototype 中。

而在 ChildClass.superclass.constructor.call(this); 这句上, BaseClass 的 f1 成了 ChildClass 的变量,而不是 ChildClass.prototype 。

通过对 JavaScript 的原型继承的了解,可以知道,实例变量的优先级是高于 prototype 的,所以上面的这个代码是达不到 override 的功能的。

 

修改的方式如下:

BaseClass = function () {

};

 

BaseClass . prototype = {

    f1 :

 function () {

        alert ( "f1inbase" );

    }

};

 

代码解读

JavaScript 中的继承实现

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

function Extend ( subFn , superFn ){

    subFn . prototype = new superFn ()

    subFn . prototype . constructor = subFn

}

 

function Animal (){

    this . say1 = function (){

        alert ( "Animal" );

    }

}

 

function Tiger (){

    this . say2 = function (){

        alert ( "Tiger" );

    }

}

 

Extend ( Tiger , Animal );

 

var tiger = new Tiger ();

tiger.say1();// "Animal"

tiger.say2();// "Tiger"

 

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

 

Ext.extend 的代码

Ext.extend 函数中用到了 Ext.override ,这个函数把第二个参数中的所有对象复制到第一个对象的 prototype 中。

首先贴上 Ext.override 函数的代码:

Ext . override = function ( origclass , overrides ){

    if ( overrides ){

       var p = origclass . prototype ;

       for ( var method in overrides ){

           p [ method ] = overrides [ method ];

       }

    }

}

 

然后贴上 Ext.extend 的代码:

 

/**

  * 继承,并由传递的值决定是否覆盖原对象的属性

  * 返回的对象中也增加了 override() 函数,用于覆盖实例的成员

  * @param { Object } subclass 子类,用于继承(该类继承了父类所有属性,并最终返回该对象)

  * @param { Object } superclass 父类,被继承

  * @param { Object } overrides (该参数可选) 一个对象,将它本身携带的属性对子类进行覆盖

  * @method extend

  */

function extend (){

    //inlineoverrides

    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 ;

    };

}();

 

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

function extend (){

    //inlineoverrides

    var inlineOverride = function ( o ){

        for ( var m in o ) {

            this [ m ] = o [ m ];

        }

    };

    return function ( subFn , superFn , overrides ){

        if ( typeof superFn == 'object' ) {

           // 如果 subFn 也是对象的话(一般来说 subFn 这里放的是父类的构造函数),那么第三个参数 overrides 参数相当于被忽略掉

            overrides = superFn ;

            superFn = subFn ;

           //subFn 重新定义了函数

            subFn = function (){

                superFn . apply ( this , arguments );

            };

        }

        var F = function (){

        }, subFnPrototype , superFnPrototype = superFn . prototype ;

        F . prototype = superFnPrototype ;

         subFnPrototype = subFn . prototype = new F ();

       subFnPrototype . constructor = subFn ;

       subFn . superclass = superFnPrototype ;

       

       if ( superFnPrototype . constructor == Object . prototype . constructor ) {

            superFnPrototype . constructor = superFn ;

        }

        subFn . override = function ( obj ){

            Ext . override ( subFn , obj );

        };

        subFnPrototype . override = inlineOverride ;

        Ext . override ( subFn , overrides );

        return subFn ;

    };

};

 

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

 

两个参数的 Ext.extend 代码

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

// 两个参数的时候的代码,注意第二个参数必须为 object

function extend (){

    //inlineoverrides

    var inlineOverride = function ( o ){

        for ( var m in o ) {

            this [ m ] = o [ m ];

        }

    };

    return function ( superFn , overrides ){

       var subFn = function (){

           superFn . apply ( this , arguments );

       };

 

        var F = function (){

        }, subFnPrototype , superFnPrototype = superFn . prototype ;

      

        F . prototype = superFnPrototype ;

       // 注意下面两句就是上面最简单的继承实现。

        subFnPrototype = subFn . prototype = new F ();

       subFnPrototype . constructor = subFn ;

       // 添加了 superclass 属性指向 superFn 的 Prototype

       subFn . superclass = superFnPrototype ;

      

       // 为 subFn 和 subFnPrototype 添加 override 函数

        subFn . override = function ( obj ){

            Ext . override ( subFn , obj );

        };

        subFnPrototype . override = inlineOverride ;

       

       // 覆盖掉子类 prototype 中的属性

        Ext . override ( subFn , overrides );

        return subFn ;

    };

};

从注释中可以看到,做的工作很简单,只是定义一个 subFn 函数,这个函数中会调用 superFn 函数。

定义了 subFn 以后,就使用上面的最简单的继承方式实现继承。

然后为 subFn 和 subFn 的 prototype 添加了一个 override 函数。

最后的 Ext.override(subFn,overrides); 把 overrides 中的函数写入 subFn 的 prototype 中。

 

三个参数的 Ext.extend 代码

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

// 三个参数时的代码

function extend (){

    //inlineoverrides

    var inlineOverride = function ( o ){

         for ( var m in o ) {

            this [ m ] = o [ m ];

        }

    };

    return function ( subFn , superFn , overrides ){

        var F = function (){

        }, subFnPrototype , superFnPrototype = superFn . prototype ;

      

        F . prototype = superFnPrototype ;

       // 注意下面两句就是上面最简单的继承实现。

        subFnPrototype = subFn . prototype = new F ();

       subFnPrototype . constructor = subFn ;

       // 添加了 superclass 属性指向 superFn 的 Prototype

       subFn . superclass = superFnPrototype ;

 

       // 为 subFn 和 subFnPrototype 添加 override 函数

        subFn . override = function ( obj ){

            Ext . override ( subFn , obj );

        };

        subFnPrototype . override = inlineOverride ;

       

       // 覆盖掉子类 prototype 中的属性

        Ext . override ( subFn , overrides );

        return subFn ;

    };

};

 

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

总结及说明

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

 

注意下面一段代码:

if ( superFnPrototype . constructor == Object . prototype . constructor) {

    superFnPrototype . constructor = superFn ;

}

详解Ext.extend的使用方法

这段代码我在改写的 Ext.extend 中省略掉了。

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

但是发现 superFn 也时 functionObject(){} ,在 IE 和 FF 下都是如此。

那么我就不是很清楚这段代码到底是什么用的了,若有清楚的,告诉一声,哈

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2