欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Extjs4 源码-Ext.extend解读

程序员文章站 2022-07-15 10:18:30
...
    Ext.apply(Ext, {

        
        extend: function() {
            
            var objectConstructor = objectPrototype.constructor,
                inlineOverrides = function(o) {
                for (var m in o) {
                    if (!o.hasOwnProperty(m)) {
                        continue;
                    }
                    this[m] = o[m];
                }
            };

            return function(subclass, superclass, overrides) {
                
                if (Ext.isObject(superclass)) {
                    overrides = superclass;
                    superclass = subclass;
                    subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
                        superclass.apply(this, arguments);
                    };
                }

                if (!superclass) {
                    Ext.Error.raise({
                        sourceClass: 'Ext',
                        sourceMethod: 'extend',
                        msg: 'Attempting to extend from a class which has not been loaded on the page.'
                    });
                }

                
                var F = function() {},
                    subclassProto, superclassProto = superclass.prototype;

                F.prototype = superclassProto;
                subclassProto = subclass.prototype = new F();
                subclassProto.constructor = subclass;
                subclass.superclass = superclassProto;

                if (superclassProto.constructor === objectConstructor) {
                    superclassProto.constructor = superclass;
                }

                subclass.override = function(overrides) {
                    Ext.override(subclass, overrides);
                };

                subclassProto.override = inlineOverrides;
                subclassProto.proto = subclassProto;

                subclass.override(overrides);
                subclass.extend = function(o) {
                    return Ext.extend(subclass, o);
                };

                return subclass;
            };
        }(),

        
        override: function(cls, overrides) {
            if (cls.prototype.$className) {
                return cls.override(overrides);
            }
            else {
                Ext.apply(cls.prototype, overrides);
            }
        }
    });

        针对原型和构造器的重写,会影响到重写前所创建实例的一些重要特性-例如继承性的识别。因此这种重写通常被要求在引擎最先装入的代码中进行。令人遗憾的是,开发人员通常无法保证这一点。所以在多个JavaScript扩展框架复合使用的情况下,经常会因此而出现不可控制的局面。

function MyObject() {
}
var obj1 = new MyObject();

MyObject.prototype.type = 'MyObject';
MyObject.prototype.value = 'test';
var obj2 = new MyObject();

MyObject.prototype = {
        constructor: MyObject,   //<--重写原型时应该维护该属性
        type: 'Bird',
        fly: function()  {/*...*/}
}
var obj3 = new MyObject();

//显示对象的属性
alert(obj1.type);
alert(obj2.type);
alert(obj3.type);

        在这个例子中,第1~7行代码创建了obj1与obj2两个对象,由于第5~6行只进行了“原型修改”,因此根据原型继承的实质我们知道obj1与obj2是类相同的两个实例。第9~13行则将原型重写成一个新的对象。不幸的是,这种重写事实上破坏了原型继承链,其直接的结果就是:obj3与obj1、obj2完全不同-这种不同甚至直接扩展到继承关系的识别上。例如:

//(续上例)
//显示false
alert(obj1 instanceof MyObject);
alert(obj2 instanceof MyObject);
//显示true
alert(obj3 instanceof MyObject);

         对一个函数的原型继承技巧:

function A() {
       alert('a');
}

//B继承A的原型
function B() {
}

//情况1
B.prototype = new A();

//情况2
var F = function() {};
F.prototype = A.prototype;
B.prototype = new F();

        情况2比情况1好的地方在于情况2没有执行alert('a')操作,当我们不希望集成过程中执行父函数的构造方法时就可以借助空函数,空函数的原型是指向复函数的原型的引用。然后子函数再继承空函数从而达到原型继承的目的。