Ext.create细节分析
var win1 = Ext.create('Ext.window.Window', { //实例化方法四 : 使用 完整的 Extjs 类名 width: 800, title: 'define test4', height:600 });
主要涉及到Ext.js Inventory.js ClassManager.js Class.js Loader.js Boot.js
在ClassManager.js中,
create: function () { var name = arguments[0], nameType = typeof name, args = arraySlice.call(arguments, 1), cls; if (nameType === 'function') { cls = name; } else { if (nameType !== 'string' && args.length === 0) { args = [name]; if (!(name = name.xclass)) { name = args[0].xtype; if (name) { name = 'widget.' + name; } } } //<debug> if (typeof name !== 'string' || name.length < 1) { throw new Error("[Ext.create] Invalid class name or alias '" + name + "' specified, must be a non-empty string"); } //</debug> name = Manager.resolveName(name); // resolveName 在 Inventory.js中,好像是根据简称获取全名 cls = Manager.get(name); // 根据名称获得类 } // Still not existing at this point, try to load it via synchronous mode as the last resort if (!cls) { //<debug> //<if nonBrowser> !isNonBrowser && // 看不懂,怎么就知道没加载该类的js文件呢 //</if> Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " + "Ext.require('" + name + "') above Ext.onReady"); // 这里就是debug版经常看到的提示require类的日志,平时都懒得挨个require //</debug> Ext.syncRequire(name); // 加载类的js cls = Manager.get(name); } //<debug> if (!cls) { throw new Error("[Ext.create] Unrecognized class name / alias: " + name); } if (typeof cls !== 'function') { throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated."); } //</debug> return Manager.getInstantiator(args.length)(cls, args); // 生成该类的实例
// 这里分为两部分看
// Manager.getInstantiator(args.length)是一个函数对象,来路见下面代码块分析
// Manager.getInstantiator(args.length)(cls, args)执行了这个函数,就 new 了一个 cls 类型的实例
// 从而我们就实现了Ext.create给定一个类名,得到这个类,然后得到这个类的一个实例,这里的类实际是自定义的引用类型
// 可以理解为一个创建实例的自定义function,在Ext.define里定义的,Ext.define细节可以看看我的Ext.define细节分析文章
},
/** * @private * @param length */ getInstantiator: function(length) { var instantiators = this.instantiators, instantiator, i, args; instantiator = instantiators[length]; // 有个缓存机制 if (!instantiator) { i = length; args = []; for (i = 0; i < length; i++) { args.push('a[' + i + ']'); } instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')'); // 这里组合出了一个函数
/* 展开实际是
function (c, a){
return new c(a[0], a[1]..., a[length - 1])
}
这样就巧妙的实现了根据一个字符串的引用类型来创建该类型的实例,
如果是Ext的基本类那么肯定不用管了,如果是自定义引用类型在Ext.define时就应该添加到Ext的类型中了,作为一个function
*/
//<debug> instantiator.name = "Ext.create" + length; //</debug> } return instantiator; },