Extjs4 源码分析系列一 类的创建过程
来源:互联网 发布:立项依据怎么写 知乎 编辑:程序博客网 时间:2024/04/26 06:36
Extjs源码分析
第一次写博客,以下是我个人阅读了Extjs的源码,借鉴了Extjs权威指南这本书的部分内容,和自己的一些调试,写出了我自己对Extjs的架构和源码级别的一些理解和认知.写的不好的地方,还请各位看官多多包涵,提出宝贵意见.
本文省略了源码中的一些调试语句,只针对关键部分进行讲解.
从Ext的四个基础的classs开始,先看src/class/目录下面的四个js文件:Base.js,Class.js,ClassManager.js,Loader.js.
Base.js中定义了 Base = function(){},也就是说Base是一个function,然后又调用Ext.apply(Base, {}),给function Base 添加了一些属性和方法,可以说Base是所有类的基类.ClassManager.js这个js文件是管理Ext的类系统的,Class.js是用来生成类的,Loader.js是用来动态加载js文件的.
我们先从这里开始分析,一般在Extjs中,我们常常这样定义一个类Ext.define(‘AAA’,{}),Ext.define这个方法在ClassManager.js文件中.
1
2
3
4
define: function (className, data, createdFn) {
//调用Manager的静态方法create
return Manager.create.apply(Manager, arguments);
},
这里又调用了Manager 的create方法,第一个参数为class的名字,第二个 参数为传入的配置对象,第三个参数为创建了class后的回调函数.
复制代码
create: function(className, data, createdFn) {
//ctor指向一个function constructor var ctor = makeCtor(); if (typeof data == 'function') { data = data(ctor); } data.$className = className; //调用 Class.js文件的 Class的构造方法 //第三个参数是onCreated return new Class(ctor, data, function() {.....});
}
复制代码
值得注意的是makeCtor这个方法.
1
2
3
4
5
6
7
function makeCtor () {
function constructor () {
return this.constructor.apply(this, arguments) || null; } return constructor;}
这里是一个闭包,返回了 function constructor,这里的用途是在实例化class的时候执行Class的构造方法用的,
更详细的我会在Ext.create方法的源码解读时来分析.接下来给data,也就是传入的配置项添加了一个属性$className,保存类名,接下来new Class(ctor, data, function() {…….}) ;Class这个类的源代码在Class.js中,我们暂时先不去管最后一个参数,也就是那个回调函数,这个在类创建的最后一步才会体现出他的作用.
Class.js中定义了 Ext.Class = ExtClass = function(Class, data, onCreated) {…},之后又Ext.执行了apply(ExtClass, {}),给ExtClass这个function添加了一些静态方法,包括了后面需要调用的create方法.下面我们来看一下 ExtClass中又做了些什么?
复制代码
Ext.Class = ExtClass = function(Class, data, onCreated) {
//这是用来调整参数位置的,new Class(ctor, data, function() {},如果ctor不是function 需要调整参数,这里 不去关注
if (typeof Class != ‘function’) {
onCreated = data;
data = Class;
Class = null;
}
if (!data) {
data = {};
}
//调用Class的静态方法create
Class = ExtClass.create(Class, data);
//执行Class的处理器
ExtClass.process(Class, data, onCreated);
return Class;};
复制代码
这里看到了执行了ExtClass的create方法和process方法.先来看create方法,这里很简单,就是把Ext.Base这个类的静态方法和属性全都复制到传入的class中,这个class实际上就是makeCtor()这个方法返回的function constructor,源代码如下:
复制代码
create: function(Class, data) {
var name, i;
if (!Class) { Class = makeCtor( //<debug> data.$className //</debug> ); } //拷贝Ext.Base类的静态方法到子类Class上 for (i = 0; i < baseStaticMemberLength; i++) { name = baseStaticMembers[i]; Class[name] = Base[name]; } return Class; }
复制代码
接下来比较重要的是process方法,这个方法比较长,乍看比较复杂,其实仔细看看也很容易理解.
先贴上源代码:
复制代码
process: function(Class, data, onCreated) {
//ext 预制的几个处理器 ,有三个必须执行的是 className ,loader,extend
/**
*
defaultPreprocessors:
0: “className”
1: “loader”
2: “extend”
3: “statics”
4: “inheritableStatics”
5: “config”
6: “mixins”
7: “alias”
length: 8
registeredPreprocessors:
registeredPreprocessors: Object alias: Object fn: function (cls, data) { name: "alias" properties: Array[2] __proto__: Object className: Object fn: function (cls, data) { name: "className" properties: true __proto__: Object config: Object fn: function (Class, data) { name: "config" properties: Array[1] __proto__: Object extend: Object fn: function (Class, data, hooks) { name: "extend" properties: true __proto__: Object inheritableStatics: Object fn: function (Class, data) { name: "inheritableStatics" properties: Array[1] __proto__: Object loader: Object fn: function (cls, data, hooks, continueFn) { name: "loader" properties: true __proto__: Object mixins: Object fn: function (Class, data, hooks) { name: "mixins" properties: Array[1] __proto__: Object statics: Object fn: function (Class, data) { name: "statics" properties: Array[1] __proto__: Object */ 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); } //如果preprocessorsProperties 不是true,是数组的话 else if (preprocessorsProperties) { for (j = 0,subLn = preprocessorsProperties.length; j < subLn; j++) { preprocessorProperty = preprocessorsProperties[j]; //并且在data中配置了该处理器的key,如inheritableStatics if (data.hasOwnProperty(preprocessorProperty)) { preprocessors.push(preprocessor.fn); break; } } } } else { preprocessors.push(preprocessor); } } //onCreated是ClassManger.js中 create 方法 return new Class(ctor, data, function() )的第三个参数 hooks.onCreated = onCreated ? onCreated : Ext.emptyFn; hooks.preprocessors = preprocessors; //执行处理器 this.doProcess(Class, data, hooks); }
复制代码
首先判断配置项中是否配置了preprocessors属性,如果没有的话采用默认的预处理器栈,
这是一个数组[‘className’,’loader’,’extend’,’statics’,’inheritableStatics’,’config’,’mixins’,’alias’],registerPreprocessors的值通过debug可以看到如下图
registeredPreprocessors: Object
alias: Object
fn: function (cls, data) {
name: “alias”
properties: Array[2]
proto: Object
className: Object
fn: function (cls, data) {
name: “className”
properties: true
proto: Object
config: Object
fn: function (Class, data) {
name: “config”
properties: Array[1]
proto: Object
extend: Object
fn: function (Class, data, hooks) {
name: “extend”
properties: true
proto: Object
inheritableStatics: Object
fn: function (Class, data) {
name: “inheritableStatics”
properties: Array[1]
proto: Object
loader: Object
fn: function (cls, data, hooks, continueFn) {
name: “loader”
properties: true
proto: Object
mixins: Object
fn: function (Class, data, hooks) {
name: “mixins”
properties: Array[1]
proto: Object
statics: Object
fn: function (Class, data) {
name: “statics”
properties: Array[1]
proto: Object
这是具体的值.
接下来就是循环 preprocessor数组,在根据数组的值作为key,在registerProprocessor中找到,然后判断处理器的properties的值是否为true,如果为true,是一定要先执行的处理器,默认有三个预处理器:className,loader,extend,如果preprocessorsProperties 不是true,是数组的话,那么久需要判断出入的配置项是否配置了该处理器的配置,如果配置了的话,也需要push到preprocessors数组中,最后添加到hooks对象上,调用this.doProcess(Class, data, hooks),注意这里的this指向的是function ExtClass,也就是调用ExtClass的静态方法doProcess.
下面在看doProcess的源代码:
复制代码
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; } } //执行Ext.Class的静态方法 onBeforeCreated hooks.onBeforeCreated.apply(me, arguments); },
复制代码
从hooks.preprocessors 数组中依次弹出处理器,并调用处理器的方法,传入ExtClass,Class,data配置,hooks,和doProcess方法,如果执行处理器的执行结果为false,就返回,不在执行后面的处理器,class初始化失败.最后执行hooks.onBeforeCreated方法,这个就是之前我们说的new Class(ctor, data, function() {…….}) ,执行第三个参数,即回调函数.
转自博客园”ace1234”
- Extjs4 源码分析系列一 类的创建过程
- lucene4.5源码分析系列:索引的创建过程
- Mybatis 源码分析一、 SqlSessionFactory的创建过程
- Rxjava2源码分析(一):Flowable的创建和基本使用过程分析
- cocos2dx源码分析:shader的创建过程
- PDF阅读器系列之--MuPDF源码分析过程(一)
- PDF阅读器系列之--MuPDF源码分析过程(一)
- ExtJS4.0源代码分析----类系统之类的创建
- Android源码解析四大组件系列(一)---Service的启动过程分析
- nova创建虚拟机过程源码简要分析(一)
- ExtJS4学习笔记(一)---window的创建
- ExtJS4学习笔记(一)---window的创建
- ExtJS4学习笔记(一)---window的创建
- [Android源码分析]L2CAP的创建过程分析
- Android源码解析Window系列第(一)篇---Window的基本认识和Activity的Window创建过程
- mongoose源码分析系列一
- mongoose源码分析系列一
- Netty源码分析系列1——NIOEventLoopGroup的创建
- 二叉树的前序、中序、后续遍历,递归、非递归实现
- AICL(Auto Input Current Limited)
- 《深入浅出struts2》--第四章,OGNL
- QListWidget实现图片缩略图形式的列表
- Day02笔记
- Extjs4 源码分析系列一 类的创建过程
- JAVA之ConcurrentHashMap源码深度分析
- ant.xml文件
- C# 属性和字段 get set
- 分布式网站架构后续:zookeeper技术浅析
- drools入门(二)-----规则引擎Drools解决汽水问题(复杂逻辑)
- LeetCode 8 String to Integer (atoi)
- python getopt使用
- ALM损坏后的恢复步骤