Ext源码解读之一 -- extend的兑现
Ext源码解读之一 -- extend的实现
先看一个例子:
再看同样功能的第二个例子:
extend的源码:
看下overrides:
extend用的是这里介绍的第6种--组合寄生模式。
先看一个例子:
Gmis.ext.Animal = function() { this.run = function() { Gmis.util.printMessage("Animal run"); }; this.swim = function() { Gmis.util.printMessage("Animal swimming"); }; this.shout = function() { Gmis.util.printMessage("Animal shout"); } }; Gmis.ext.Cat = Ext.extend(Gmis.ext.Animal, { constructor : function() { Gmis.ext.Cat.superclass.constructor.call(this); }, run : function() { Gmis.util.printMessage("Cat run"); } }); var cat = new Gmis.ext.Cat(); cat.run(); cat.shout();
再看同样功能的第二个例子:
Gmis.ext.Animal = function(name) { this.name = name; }; Gmis.ext.Animal.prototype = { run : function() { Gmis.util.printMessage(this.name + " 2Animal run"); }, swim : function() { Gmis.util.printMessage(this.name + " 2Animal swimming"); }, shout : function() { Gmis.util.printMessage(this.name + " 2Animal shout"); } }; Gmis.ext.Cat = function(name,age){ Gmis.ext.Cat.superclass.constructor.call(this,name); this.age = age; }; Ext.extend(Gmis.ext.Cat,Gmis.ext.Animal, { run : function() { Gmis.util.printMessage(this.name + " 2Cat run, age: " + this.age); } }); var cat = new Gmis.ext.Cat("jiafei",3); cat.run(); cat.shout();
extend的源码:
extend : function(){ // inline overrides var io = function(o){ for(var m in o){ this[m] = o[m]; } }; var oc = Object.prototype.constructor; return function(sb, sp, overrides){ if(typeof sp == 'object'){ //1、在我们的第一个例子中,会走这个分支的。 //实际上是把参数调整了下,overrides等于了第二个参数-字面量对象, // 让sp等于了Gmis.ext.Animal,sb等于了字面量对象里的constructor(如果有的话) //效果实际上跟第二个例子差不多。后边可以按照第二个例子讲解了 overrides = sp; sp = sb; sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; } //2、这个F的实例可就是子类原型哦 var F = function(){}, sbp,//子类的原型 spp = sp.prototype;//超类的原型 //3、F的原型等于了超类的原型 F.prototype = spp; //4、子类的原型等于了F的一个实例 sbp = sb.prototype = new F(); //5、子类原型的构造函数设置为了子类本身,如果不设置?? sbp.constructor=sb; //6、子类的superclass属性等于了超类的原型,这样就可以直接调用子类.superclass.constructor.call(this,xxx)了 sb.superclass=spp; //7、如果超类原型的构造函数等于Object对象原型的构造函数,这里还要顺便再设置下超类原型的构造函数。 if(spp.constructor == oc){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.superclass = sbp.supr = (function(){ return spp; }); sbp.override = io; //8、把overrides里边的所有方法和字段全部拷到子类的原型中(记得是原型中),实际也是F对象的实例中 Ext.override(sb, overrides); sb.extend = function(o){return Ext.extend(sb, o);}; return sb; }; }(),//这里执行了哦,会返回一个function的
看下overrides:
override : function(origclass, overrides){ if(overrides){ var p = origclass.prototype; Ext.apply(p, overrides); if(Ext.isIE && overrides.hasOwnProperty('toString')){ p.toString = overrides.toString; } } }
extend用的是这里介绍的第6种--组合寄生模式。