透视Ext JS 4类背后的机制与特点(下)

简介: 在构建 Ext.Class 之时,它会分配既细又专的处理器(processors),专门处理构成类定义的每一个部分。当前Ext缺省提供了一些处理器,包括有:mixins 多态的,配置项函数的,以及处理类扩展的都是必备的。

在构建 Ext.Class 之时,它会分配既细又专的处理器(processors),专门处理构成类定义的每一个部分。当前Ext缺省提供了一些处理器,包括有:mixins 多态的,配置项函数的,以及处理类扩展的都是必备的。除了缺省处理器外,还可以随便自定义预处理器,预处理器是完全交给开发者可控的。因为通过分解类处理单元,就可以达到了扩展性的目的,以便允许我们针对不同的场景,去制定更合适的处理器从而满足需求(具体组装的过程可仿照下面介绍的 static 处理器举一反三)。

一图胜千言,下图即官方所出的 Ext.Class 流程图。欲了解其中原理?不妨进入流程看看大致的轮廓吧!先从最左上角的前头起前进,以此为出发点,按箭头方向走,走完就是从处理器的角度看的流程。至于还有一个角度,就是正下方的“Define”到“Callback”的流程,这是站在 Ext.Class 其总体上“输入、输出”的角度来来看。无论出于哪个角度,皆是围绕于 Ext.Class 的内部工作流进行的。

处理器(processors)分预处理器(preprocessors)和后处理器两种(postprocessors)。按照原作者Ed解释道,一旦类“准备好了(ready)”就是认为是预处理器执行完毕的阶段,这时候可以把类实例化了可称为 “ready”;剩下的就属于后处理器的阶段——两者就是根据这样来区分的。典型地,后处理器负责如类简写方式 xtype,兼容旧版,还有向 Manager 登记之类的任务,总之都是围绕类的后期工作,而绝对不会影响类的逻辑行为。

Ext.Class 构造器内部中透过送入回调函数来达成处理器之间的接力,也就是说,其过程不是同步的。之所以执行处理器的每一步都是异步的(asynchronously)是为了便于实现异步加载。排在预处理器列表中第一个便是 Loader,用于加载页面上却还没有的类。我们前面的教程中已经为大家介绍过关于Loader的用法,而其中异步加载的秘密正在于此!

运行完 Loader 之后,Ext.Class 安排 Extend 的预处理器接着进行,然后是 Mixins 多态、Config 等等,最后就是 static 处理的部分。流程如上图所示。

预处理器其运行是完全可控的,可以随便自定义预处理器的每一步。好比静态的处理器,我们就详细的看看 static 预处理器是如何写的:

Ext.Class.registerPreprocessor('statics', function(cls, data, callback) { if (Ext.isObject(data.statics)) { var statics = data.statics, name; // 原理只是简单地拷贝一下 for (name in statics) { if (statics.hasOwnProperty(name)) { cls[name] = statics[name]; } } } delete data.statics; // 已经完成好了当前预处理器,可进入下一个预处理器。 if (callback) { callback.call(this, cls, data); } }); // 改变数组的顺序便可以改变加载预处理器的顺序。 Ext.Class.setDefaultPreprocessors(['extend', 'mixins', 'config', 'statics']);

上述过程其实非常直观易明。我们登记了Ext.Class 的一个预处理器名曰 “static”,同时一定要传入的就是这个 static 所对应的函数(第二个参数),它会传入刚刚建立的Ext.Class,也就是那个新类,以及类的配置参数和回调函数(在预处理器执行后的回调函数),构成三个的参数传入。由代码可见,static 预处理器的工作量其实没什么,只是看看我们有否声明了 static 属性,有的话便拷贝 static  配置项对象到类对象身上。例如我们打算写一个 getNextId 的静态方法分配给类。写法如下:

Ext.define('MyClass', { statics: { idSeed: 1000, getNextId: function() { return this.idSeed++; } } });

静态处理器产生的是静态成员,所以直接可以在类身上调用方法,不用创建 MyClass 实例。

MyClass.getNextId(); //1000 MyClass.getNextId(); //1001 MyClass.getNextId(); //1002 ... 等等

最后一步,就是就是运行 callback 的回调函数(在上图中有指示的)。此时此刻,您就可以在程序中使用这个类了。于是,我们就在这个回调中实例化 MyClass,如果成功也就明确了 Ext.Window 所依赖的对象均加载回来了。

Ext.define('MyClass', { extend: 'Ext.Window' }, function() { // MyClass此时此刻可用了 var cls = new MyClass(); cls.setTitle('Everything is ready'); cls.show(); });

最后一点,性能。毋庸讳言,复杂的代码会降低性能——连主程 Ed 都承认这点。他说,虽然比较复杂,但为了灵活性和易用性,就是算上这些代价,也是值得的。

参考资料:

目录
相关文章
|
1月前
|
JavaScript
js开发:请解释什么是ES6的类(class),并说明它与传统构造函数的区别。
ES6的类提供了一种更简洁的面向对象编程方式,对比传统的构造函数,具有更好的可读性和可维护性。类使用`class`定义,`constructor`定义构造方法,`extends`实现继承,并可直接定义静态方法。示例展示了如何创建`Person`类、`Student`子类以及它们的方法调用。
22 2
|
1月前
|
JavaScript 前端开发
js开发:请解释原型继承和类继承的区别。
JavaScript中的原型继承和类继承用于共享对象属性和方法。原型继承利用原型链查找属性,节省内存但不支持私有成员。类继承通过ES6的class和extends实现,支持私有成员但占用更多内存。两者各有优势,适用于不同场景。
19 0
|
1月前
|
设计模式 JavaScript 前端开发
深入理解 JavaScript 中的绑定机制(下)
深入理解 JavaScript 中的绑定机制(下)
|
1月前
|
JavaScript 前端开发
深入理解 JavaScript 中的绑定机制(上)
深入理解 JavaScript 中的绑定机制(上)
|
1月前
uni-app 65egg.js聊天类chat.js封装(二)
uni-app 65egg.js聊天类chat.js封装(二)
25 1
|
29天前
|
开发框架 JavaScript 前端开发
描述JavaScript事件循环机制,并举例说明在游戏循环更新中的应用。
JavaScript的事件循环机制是单线程处理异步操作的关键,由调用栈、事件队列和Web APIs构成。调用栈执行函数,遇到异步操作时交给Web APIs,完成后回调函数进入事件队列。当调用栈空时,事件循环取队列中的任务执行。在游戏开发中,事件循环驱动游戏循环更新,包括输入处理、逻辑更新和渲染。示例代码展示了如何模拟游戏循环,实际开发中常用框架提供更高级别的抽象。
13 1
|
30天前
|
JavaScript 前端开发 算法
深入探讨前端框架Vue.js中的虚拟DOM机制
本文将深入探讨前端框架Vue.js中的虚拟DOM机制,分析其原理、优势以及在实际开发中的应用场景,帮助读者更好地理解Vue.js框架的核心特性。
|
1月前
|
消息中间件 前端开发 JavaScript
深入理解JavaScript中的事件循环机制
JavaScript作为一种前端开发必备的编程语言,在处理异步操作时常常涉及到事件循环机制。本文将深入探讨JavaScript中事件循环的工作原理,帮助读者更好地理解和运用这一关键概念。
|
1月前
|
自然语言处理 JavaScript 前端开发
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)
|
1月前
|
JavaScript 前端开发
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(上)
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(上)