ext/src/class/ClassManager.js

// todo 源码分析



重要:包含了Ext.define的定义

Ext.apply(Ext, {* the class' constructor.* @return {Object} instance* @member Ext* @method create*/create: alias(Manager, 'instantiate'),** @member Ext* @param {String} [name] The xtype of the widget to create.* @param {Object} [config] The configuration object for the widget constructor.* @return {Object} The widget instance*/widget: function(name, config) {// forms://      1: (xtype)//      2: (xtype, config)//      3: (config)//      4: (xtype, component)//      5: (component)//      var xtype = name,alias, className, T, load;if (typeof xtype != 'string') { // if (form 3 or 5)// first arg is config or componentconfig = name; // arguments[0]xtype = config.xtype;} else {config = config || {};}if (config.isComponent) {return config;}alias = 'widget.' + xtype;className = Manager.getNameByAlias(alias);// this is needed to support demand loading of the classif (!className) {load = true;}T = Manager.get(className);if (load || !T) {return Manager.instantiateByAlias(alias, config);}return new T(config);},/*** @inheritdoc Ext.ClassManager#instantiateByAlias* @member Ext* @method createByAlias*/createByAlias: alias(Manager, 'instantiateByAlias'),* required. Otherwise, the override, like the target class, is not included.** @param {String} className The class name to create in string dot-namespaced format, for example:* 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'* It is highly recommended to follow this simple convention:*  - The root and the class name are 'CamelCased'*  - Everything else is lower-cased* Pass `null` to create an anonymous class.* @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid* strings, except those in the reserved listed below:*  - `mixins`*  - `statics`*  - `config`*  - `alias`*  - `self`*  - `singleton`*  - `alternateClassName`*  - `override`** @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which* (`this`) will be the newly created class itself.* @return {Ext.Base}* @member Ext*/define: function (className, data, createdFn) {//<debug>Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments);//</debug>if (data.override) {return Manager.createOverride.apply(Manager, arguments);}// create方法源码见后面return Manager.create.apply(Manager, arguments);},/*** Undefines a class defined using the #define method. Typically used* for unit testing where setting up and tearing down a class multiple* times is required.  For example:* *     // define a class*     Ext.define('Foo', {*        ...*     });*     *     // run test*     *     // undefine the class*     Ext.undefine('Foo');* @param {String} className The class name to undefine in string dot-namespaced format.* @private*/undefine: function(className) {//<debug>Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments);//</debug>var classes = Manager.classes,maps = Manager.maps,aliasToName = maps.aliasToName,nameToAliases = maps.nameToAliases,alternateToName = maps.alternateToName,nameToAlternates = maps.nameToAlternates,aliases = nameToAliases[className],alternates = nameToAlternates[className],parts, partCount, namespace, i;delete Manager.namespaceParseCache[className];delete nameToAliases[className];delete nameToAlternates[className];delete classes[className];if (aliases) {for (i = aliases.length; i--;) {delete aliasToName[aliases[i]];}}if (alternates) {for (i = alternates.length; i--; ) {delete alternateToName[alternates[i]];}}parts  = Manager.parseNamespace(className);partCount = parts.length - 1;namespace = parts[0];for (i = 1; i < partCount; i++) {namespace = namespace[parts[i]];if (!namespace) {return;}}// Old IE blows up on attempt to delete window propertytry {delete namespace[parts[partCount]];}catch (e) {namespace[parts[partCount]] = undefined;}},/*** @inheritdoc Ext.ClassManager#getName* @member Ext* @method getClassName*/getClassName: alias(Manager, 'getName'),/*** Returns the displayName property or className or object. When all else fails, returns "Anonymous".* @param {Object} object* @return {String}*/getDisplayName: function(object) {if (object) {if (object.displayName) {return object.displayName;}if (object.$name && object.$class) {return Ext.getClassName(object.$class) + '#' + object.$name;}if (object.$className) {return object.$className;}}return 'Anonymous';},/*** @inheritdoc Ext.ClassManager#getClass* @member Ext* @method getClass*/getClass: alias(Manager, 'getClass'),/*** Creates namespaces to be used for scoping variables and classes so that they are not global.* Specifying the last node of a namespace implicitly creates all other nodes. Usage:**     Ext.namespace('Company', 'Company.data');**     // equivalent and preferable to the above syntax*     Ext.ns('Company.data');**     Company.Widget = function() { ... };**     Company.data.CustomStore = function(config) { ... };** @param {String...} namespaces* @return {Object} The namespace object.* (If multiple arguments are passed, this will be the last namespace created)* @member Ext* @method namespace*/namespace: alias(Manager, 'createNamespaces')});



create方法源码,如下:

create: function(className, data, createdFn) {//<debug error>if (className != null && typeof className != 'string') {throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string");}//</debug>var ctor = makeCtor(); // why?if (typeof data == 'function') {data = data(ctor);}//<debug>if (className) {ctor.displayName = className;}//</debug>data.$className = className;// 详见ExtClass源码return new Class(ctor, data, function() {var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors,registeredPostprocessors = Manager.postprocessors,postprocessors = [],postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty;delete data.postprocessors;for (i = 0,ln = postprocessorStack.length; i < ln; i++) {postprocessor = postprocessorStack[i];if (typeof postprocessor == 'string') {postprocessor = registeredPostprocessors[postprocessor];postprocessorProperties = postprocessor.properties;if (postprocessorProperties === true) {postprocessors.push(postprocessor.fn);}else if (postprocessorProperties) {for (j = 0,subLn = postprocessorProperties.length; j < subLn; j++) {postprocessorProperty = postprocessorProperties[j];if (data.hasOwnProperty(postprocessorProperty)) {postprocessors.push(postprocessor.fn);break;}}}}else {postprocessors.push(postprocessor);}}data.postprocessors = postprocessors;data.createdFn = createdFn;Manager.processCreate(className, this, data);});}