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”

0 0
原创粉丝点击