Extjs4 源码-Ext.extend解读

    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')操作,当我们不希望集成过程中执行父函数的构造方法时就可以借助空函数,空函数的原型是指向复函数的原型的引用。然后子函数再继承空函数从而达到原型继承的目的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值