需要把Ext.define格式的假类,转化成真正的类(或function)。
Ext.define()方法中调用ClassManager的create()方法,
该方法会调用new Class(也就是Ext.Class)
Ext.Class的定义如下:
/** * @method constructor * Create a new anonymous class. * * @param {Object} data An object represent the properties of this class * @param {Function} onCreated Optional, the callback function to be executed when this class is fully created. * Note that the creation process can be asynchronous depending on the pre-processors used. * * @return {Ext.Base} The newly created class */ Ext.Class = ExtClass = function(Class, data, onCreated) { if (typeof Class != 'function') { onCreated = data; data = Class; Class = null; } if (!data) { data = {}; } Class = ExtClass.create(Class, data); ExtClass.process(Class, data, onCreated); return Class; };
Ext.Class位于:ext/src/class/Class.js 是一个自执行函数
(function() { var ExtClass, Base = Ext.Base, baseStaticMembers = [], baseStaticMember, baseStaticMemberLength; /** * baseStaticMember中存放的是Base中的静态属性和方法 * 可以见本文附录,源代码在src/class/Base.js */ for (baseStaticMember in Base) { if (Base.hasOwnProperty(baseStaticMember)) { baseStaticMembers.push(baseStaticMember); } } baseStaticMemberLength = baseStaticMembers.length; // Creates a constructor that has nothing extra in its scope chain. function makeCtor (className) { // 构造函数 function constructor () { // Opera has some problems returning from a constructor when Dragonfly isn't running. The || null seems to // be sufficient to stop it misbehaving. Known to be required against 10.53, 11.51 and 11.61. return this.constructor.apply(this, arguments) || null; } //if (className) { constructor.displayName = className; } // return constructor; } /** * @method constructor * Create a new anonymous class. * * @param {Object} data An object represent the properties of this class * @param {Function} onCreated Optional, the callback function to be executed when this class is fully created. * Note that the creation process can be asynchronous depending on the pre-processors used. * * @return {Ext.Base} The newly created class */ Ext.Class = ExtClass = function(Class, data, onCreated) { if (typeof Class != 'function') { onCreated = data; data = Class; Class = null; } if (!data) { data = {}; } Class = ExtClass.create(Class, data); // 这里定义了Class关键字,并且调用create方法,见下面 ExtClass.process(Class, data, onCreated); // 调用拦截器 return Class; }; Ext.apply(ExtClass, { /** * @private */ onBeforeCreated: function(Class, data, hooks) { // create之前的事件拦截 //Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '>> Ext.Class#onBeforeCreated', arguments); // Class.addMembers(data); hooks.onCreated.call(Class, Class); //Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '<< Ext.Class#onBeforeCreated', arguments); // }, /** * @private */ create: function(Class, data) { // 属性复制 var name, i; if (!Class) { Class = makeCtor( //data.$className // ); } for (i = 0; i < baseStaticMemberLength; i++) { name = baseStaticMembers[i]; Class[name] = Base[name]; // 把Base中定义的属性和方法,复制到当前类 } return Class; }, /** * @private */ process: function(Class, data, onCreated) { // 处理拦截事件 var preprocessorStack = data.preprocessors || ExtClass.defaultPreprocessors, registeredPreprocessors = this.preprocessors, // hooks = { onBeforeCreated: this.onBeforeCreated }, preprocessors = [], preprocessor, preprocessorsProperties, i, ln, j, subLn, preprocessorProperty; delete data.preprocessors; for (i = 0,ln = preprocessorStack.length; i < ln; i++) { preprocessor = preprocessorStack[i]; if (typeof preprocessor == 'string') { preprocessor = registeredPreprocessors[preprocessor]; preprocessorsProperties = preprocessor.properties; if (preprocessorsProperties === true) { preprocessors.push(preprocessor.fn); } else if (preprocessorsProperties) { for (j = 0,subLn = preprocessorsProperties.length; j < subLn; j++) { preprocessorProperty = preprocessorsProperties[j]; if (data.hasOwnProperty(preprocessorProperty)) { preprocessors.push(preprocessor.fn); break; } } } } else { preprocessors.push(preprocessor); } } hooks.onCreated = onCreated ? onCreated : Ext.emptyFn; hooks.preprocessors = preprocessors; this.doProcess(Class, data, hooks); }, doProcess: function(Class, data, hooks) { var me = this, preprocessors = hooks.preprocessors, preprocessor = preprocessors.shift(), doProcess = me.doProcess; for ( ; preprocessor ; preprocessor = preprocessors.shift()) { // Returning false signifies an asynchronous preprocessor - it will call doProcess when we can continue if (preprocessor.call(me, Class, data, hooks, doProcess) === false) { return; } } hooks.onBeforeCreated.apply(me, arguments); }, /** @private */ preprocessors: {}, registerPreprocessor: function(name, fn, properties, position, relativeTo) { if (!position) { position = 'last'; } if (!properties) { properties = [name]; } this.preprocessors[name] = { name: name, properties: properties || false, fn: fn }; this.setDefaultPreprocessorPosition(name, position, relativeTo); return this; }, /** * Retrieve a pre-processor callback function by its name, which has been registered before * * @param {String} name * @return {Function} preprocessor * @private * @static */ getPreprocessor: function(name) { return this.preprocessors[name]; }, /** * @private */ getPreprocessors: function() { return this.preprocessors; }, /** * @private */ defaultPreprocessors: [], /** * Retrieve the array stack of default pre-processors * @return {Function[]} defaultPreprocessors * @private * @static */ getDefaultPreprocessors: function() { return this.defaultPreprocessors; }, setDefaultPreprocessors: function(preprocessors) { // 略 }, setDefaultPreprocessorPosition: function(name, offset, relativeName) { // 略 }, configNameCache: {}, getConfigNameMap: function(name) { var cache = this.configNameCache, map = cache[name], capitalizedName; if (!map) { capitalizedName = name.charAt(0).toUpperCase() + name.substr(1); map = cache[name] = { internal: name, initialized: '_is' + capitalizedName + 'Initialized', apply: 'apply' + capitalizedName, update: 'update' + capitalizedName, 'set': 'set' + capitalizedName, 'get': 'get' + capitalizedName, doSet : 'doSet' + capitalizedName, changeEvent: name.toLowerCase() + 'change' }; } return map; } }); ExtClass.registerPreprocessor('extend', function(Class, data, hooks) { // 略 }, true); ExtClass.registerPreprocessor('statics', function(Class, data) { // 略 }); ExtClass.registerPreprocessor('inheritableStatics', function(Class, data) { // 略 }); ExtClass.registerPreprocessor('config', function(Class, data) { // 略 }); ExtClass.registerPreprocessor('mixins', function(Class, data, hooks) { // 略 }); Ext.extend = function(Class, Parent, members) { //Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extend-backwards-compatible', arguments); // if (arguments.length === 2 && Ext.isObject(Parent)) { members = Parent; Parent = Class; Class = null; } var cls; if (!Parent) { throw new Error("[Ext.extend] Attempting to extend from a class which has not been loaded on the page."); } members.extend = Parent; members.preprocessors = [ 'extend' //,'statics' // // ,'inheritableStatics' // // ,'mixins' // // ,'config' // ]; if (Class) { cls = new ExtClass(Class, members); // The 'constructor' is given as 'Class' but also needs to be on prototype cls.prototype.constructor = Class; } else { cls = new ExtClass(members); } cls.prototype.override = function(o) { for (var m in o) { if (o.hasOwnProperty(m)) { this[m] = o[m]; } } }; return cls; }; //}());
附录,baseStaticMember: