ESOE 技术说明书 0.2 | ||
术语![]() | ||
本节列出在ESOE中所使用的术语. 术语的说明指示的是在本文中表示的含义, 而非通常意义上的严格的含义.
ESOE模块 (Modules)![]() | ||
当前版本的ESOE依功能划分为6个模块 (modules)
| 模块1 M1 : kernel | 1. 名称空间定义 2. 类定义 3. 类继承定义 4. 规范化非ESOE对象方案 5. 关键字加载和冲突方案 6. 模块加载 7. 简单调试工具 | 1. 支持ECMA-262 (第三版)的兼容语言. 2. 手工加载类库和资源. 3. 应用系统的发行版可以转化到模块1提高载入效率. |
| 模块2 M2 : resource | 1. 名称空间的物理映射定义 2. 载入资源方案 | |
| 模块3 M3 : loader | 1. 自动载入类库和类 | 1. 模块3依赖于模块2. 2. 模块3也允许手工加载类库和资源. |
| 模块4 M4 : destroy | 1. 清理函数方案 | 1. 临时性模块. 2. 本模块可能与其它所有模块相关. |
| 模块5 M5 : share | 1. 共享ESOE对象 2. 共享类库 |
1. 模块1为核心功能. 2. 其它模块不是必须的, 可依照使用功能进行组合. 3. 对一些ECMAScript系统, 可能某些模块无法实现, 且模块中的某些功能无法实现. 4. 除模块3依赖于模块2外, 各模块可独立加载. 5. 模块4是临时性模块, 如果未来出现完善的ECMAScript系统, 不存在内存泄漏问题, 可以取消模块4.
关键字类别![]() | ||
ESOE关键字依使用方式分为4个类别 (Category)
| c1 | $esoe prototype._esoe [object]._esoe | 1. 如果c1关键字发生冲突, ESOE引擎将无法工作 | |
| c2 | _ns _package _normalize _import _derive _derivex _setpath (M2) _getpath (M2) _loadres (M2) _update (M3) | $esoe.* | 1. 替代方案指将关键字替代为$esoe的对应方法. 如_package用$esoe._package替代. 2. 如果c2关键字发生冲突, 可使用nokey参数关闭这些关键字, 并使用替代方案. 3. 在应用系统的发行版, 如果要兼容非ESOE系统, 最好使用替代方案. |
| c3 | prototype._base prototype._pkg | prototype._esoe.* | 1. 替代方案指将关键字替代为prototype._esoe的对应属性. 如_base用_esoe._base 替代. 2. 对ESOE对象, c3关键字等同c4 关键字, 应由用户主动避免冲突. 3. 当规范化非ESOE对象时, 如果c3关键字发生冲突, 可关闭这些关键字, 并使用替代方案. |
| c4 | [func]._declare prototype._set prototype._destroy (M4) prototype._share (M5) $esoe.Share (M5) | 1. c4 关键字只用于ESOE对象, 理论上不会发生冲突, 或应由用户主动避免冲突. |
关键字简述![]() | ||
| $esoe | =window.$esoe, ESOE引擎自身 |
| prototype._esoe | 用于维护类/对象信息 |
| [object]._esoe | 用于维护非EOSE对象信息 |
| _ns | 预定义一个名称空间, 获取一个名称空间. |
| _package | 等同_ns, 用于系统兼容 |
| _normalize | 规范化构造器 |
| _import | 导入一个类 |
| _derive | 继承自一个类 |
| _derivex | 多继承, 或属性拷贝 |
| _setpath (M2) | 设置名称空间物理路径 |
| _getpath (M2) | 获取名称空间物理路径 |
| _loadres (M2) | 加载资源 |
| _update (M3) | 更新导入的类. 使用这个关键字激活一些载入类库的工作, 例如循环操作等. |
| prototype._base | 基类, 即基类所对应的构造器的prototype. |
| prototype._pkg | 一个类所属的最底层的包. |
| [func]._declare | 构造器的声明函数 |
| prototype._set | 类或实例的初始化函数 |
| prototype._destroy (M4) | 类或实例的清理函数/析构函数 |
| prototype._share (M5) | 类或实例的共享初始化函数 |
| $esoe.Share (M5) | 为当前GLOBAL对象创建一个共享的ESOE对象. |
ESOE布局![]() | ||
ESOE布局包括以下部分 1. 加载ESOE引擎及参数 2. 设置资源路径. 为可选部分. 3. 手工加载类库. 对M3为可选部分. 4. 加载和声明使用的类. 说明: 1. ESOE强烈建议将ESOE布局代码和用户代码分离, 将所有类声明集中放在代码项部. 虽然在多数环境中这并不是必须的. 2. 对M3, 如果使用了非ESOE类, 而且这些非ESOE类彼此间具有依赖性, 可以多次使用ESOE布局的第4部分.
ESOE对象参数![]() | ||
ESOE引擎具有可由外部传入的参数
| _param | 保存所有参数以备将来使用. |
| _path | ESOE引擎的物理路径 |
| _module | 指示要加载的模块的字串, 可选的模块代码为1,2,3,4,5. 其中1为默认加载的核心模块, 可省略. 其它模块代码以','分隔. 例子: "1" M1 (默认) "2" M1+M2 "4,5" M1+M4+M5 |
| _debug | 调试级别参数, 当前版本可设为以下值, 0: 不调试 (默认) 1: 设置为最低的调试级别 9: 设置为最高的调试级别 |
| _nokey | c2 关键字冲突列表, 如果设为'*', 禁用所有c2关键字. |
| _libpath (M2) | 默认类库加载路径, 只可设置1个. 如果未设置, 使用_path作为默认路径. |
| _libmode (M3) | 默认类库/类文件加载模式 0: 不加载任何默认类库/类文件 (默认). 1: 先加载默认类库文件, 再加载类文件. 2: 先加载类文件, 再加载默认类库文件. 3: 仅加载默认类库文件. 4: 仅加载类文件 说明: 1. 对实际的应用系统, 并非所有的加载模式都可正常工作, 应根据调试/发行/配置等具体情况进行设置. |
| _nodestroy (M4) | 在将来, 对于较完善的ECMAScript实现系统, 如果不存在内存泄漏问题, 可以关闭清理函数机制. 可选值, 0 (默认) 或1. |
名称空间定义![]() | ||
名称空间是用对象链表示的对象位置的一种方法. 在ESOE中, 任何对象链都可被称为名称空间. 对象链的根节点必然是全局对象(GLOBAL)或某个指定对象的属性, 在ESOE中称这个对象映射(Map)了所有的这个名称空间.
例如:
var obj= new Object;
obj.com= new Object;
obj.com.mycompany= new Object;
obj.com.mycompany.myclass= new Object;
以上过程在obj对象中映射了("com", "com.mycompany", "com.mycompany.myclass")名称空间, 也可以称为是在obj.com对象中映射了("mycompany", "mycompany.myclass")名称空间, 以此类推. 特别地, 也可称为在GLOBAL对象映射了"obj.com.mycompany.myclass"名称空间.
类规范化 / _normalize()![]() | ||
规范化是将类的构造器映射到$esoe.ns的过程. 在ESOE中, 对于每一个构造器 (函数), 如果它的原型 (prototype) 已预备好, 都可对它进行规范化操作. 预备好的原型指以后不会再出现对prototype的赋值操作, 但不包括对prototype的属性的操作. 例如, 规范化后, func.prototype= ...是不允许的, 但func.prototype.p1=...是允许的. ESOE系统在映射之前, 将先检查名称空间是否有冲突. 如果名称空间已被其它对象占用, 规范化过程返回false, 如果$esoe._debug>0, 会显示一个出错信息. 如果映射成功, 系统会添加一个prototype._esoe属性到构造器的原型中. 另外, 类似ECMAScript系统, 规范化过程还会做以下工作, func.prototype.constructor= func; 如果_esoe._conflict不为1, 为方便用户使用, 规范化过程会做以下工作, func.prototype._pkg = func.prototype._esoe._pkg;
设置物理路径 / _setpath() / _getpath()![]() | ||
使用_setpath()可以指定一个包所在的路径, 每个包可以指定一个路径. 一个包所包含的下一级包可以指定不同的路径. 调用 _setpath() 时路径信息被存放在$esoe._lib对应的名称空间的$path属性下.
使用_getpath()可以提取出一个包或类所在的路径. 提取出的路径包括对本包所设置的路径, 附加上本包的名称. 对于类路径, 与包路径相同, 仅须加上文件的扩展名.
例子:
如果同时设置了
_setpath("com","../lib/" );
_setpath("com.mylib","../lib2/" );
那么
"com.xtree.WebFXTree" 将从 ../lib/com/xtree/WebFXTree 加载
"com.mylib.class1"将从../lib2/ mylib/class1加载
类库文件自动加载 (M3)![]() | ||
当ESOE系统发现一个类的构造器未加载时, 会将类的名称记录于$esoe._lib对应名称空间的$fail, 并将_import的全局参数记录在$map (非全局参数不记录). 然后会尝试自动加载类库. 系统根据$esoe._libmode确定是先加载类文件还是整个包的类库文件_all. 在确认未重复加载的情况下进行以下工作, * 如果加载了任何文件, $esoe._lib.$count加1. * 如果是加载_all文件, $esoe._lib.$ext会置1. * 如果加载了文件, 将$esoe._lib对应类或包的名称空间的$inc加1. * 如果$esoe._lib.$ext已置1, 不加载类文件, 只加载_all文件.
类定义![]() | ||
在ESOE中, 类特指构造器的原型 (constructor's prototype). 但构造器也可用于指示类, 构造器和原型在对类的描述上处于同一级别.
每一个类的构造器都应该具有一个声明函数 (_declare), 这个函数是一个不带参数的函数 (Function) 对象.
[constructor]._declare= function()
{
...
}
在声明函数中, 构造器的原型可以被创建, 并且进行初始化. 如果类声明过程成功完成, _declare应返回true, 如果类声明过程出现错误, _declare应返回false. 声明函数是一个被ESOE系统所使用的回调函数.
在声明函数中, 必须进行类规范化操作.
如果要在声明函数中定义原型的方法, 应注意这些方法是使用闭包函数的方式定义的, 应减少在声明函数内和闭包函数外的位置定义新的变量. 声明函数是一个不带参数的函数, 也是为了避免这个问题.
类继承 / _derive()![]() | ||
在ESOE中, 如果一个类继承自一个基类, 将继承类的原型设置为基类的一个新实例. [class].prototype= new [baseclass]; 这一语句隐含在ESOE系统的 _derive() 过程中. 在_derive() 过程中还包括对基类和继承类的规范化操作. 如果类继承成功, 系统会添加以下属性到继承类的原型中, _esoe._base : 基类所对应的构造器的prototype. 如果_esoe._conflict不为1, 为方便用户使用, 继承操作会做以下工作, func.prototype._base= func.prototype._esoe._base; 在继承类声明函数中, 应该使用 _derive([thisclass],[baseclass]) 设置类继承关系, 而不应该直接设置prototype的值. 如果未加载M3, 所有的基类应被预先加载, 否则_dervice返回false, 继承类声明失败. 如果已加载M3, 如果基类未加载, _dervice返回false, 这时继承类的声明函数也应返回false, 等待下一次重新声明.
类属性的修饰![]() | ||
在ESOE中, 建议用户在构造器或声明函数中使用以下方式实现对类属性的修饰.
| 1 | private | 任意 | 构造函数, var声明 | 构造函数 |
| 2 | static, private | 任意 | 独立的声明函数, var声明 | 声明函数 |
| 3 | public | 变量 | 使用prototype.[propety] 声明简单变量, 并直接赋值 | 任意 |
| 4 | static, public | 对象 | 使用prototype.[propety] 声明对象变量, 并直接赋值 | 任意 |
| 5 | public | 对象 | 使用prototype.[propety] 声明对象变量, 并在_set()中赋值 | 任意 |
其中, 变量指简单变量, 如String, Number, Boolean, null等; 对象指对象变量, 如Object, Array, Function等. ESOE建议只使用表中的3,4,5方式. 方式1和2虽然可以实现属性隐藏等功能, 但同时带来代码格式不统一, 闭包函数等问题. 如果确实有必要使用, 应尽可能减少不必要的变量引用, 并使用清理函数机制.
类实例初始化 / _set()![]() | ||
ESOE系统不支持在声明时附加参数, 也就是不支持类初始化参数, 但支持类实例初始化参数. 每一个ESOE类的原型都应带有一个_set()方法, 以对类实例进行初始化. 这个方法建议使用与构造器相同的参数. _set()方法在以下情况使用, 1. 在类实例化时调用_set()方法. 2. 在有类继承的情况下, 继承类在声明时, 会调用无参数的基类构造器过程, 这时由基类自行处理_set()的无参数调用方式. 3. 在有类继承的情况下, 继承类在其自己的_set 方法中, 以call方式调用基类的_set 方法, this._base._set.call( this, ... );
共享初始化 / prototype._share![]() | ||
对于一些与运行环境交互的类, 在声明类时要求建立一个prototype._share()方法, 用于初始化类在运行时的全局环境. 这个方法在以下情况被用到, 1. 类内部与全局环境交互时, 使用由prototype._share()建立的指示全局环境的变量, 而不要直接使用全局环境. 2. 类继承时, 如果基类已有_share()方法, 继承类不必建立_share()方法. 3. 在使用_import()关键字时, ESOE系统将创建一个空的继承类, 并以当前全局环境为参数调用新类的_share方法. 在实现时应注意新类参数的传递问题. 提示: ESOE的类共享策略会使运行效率稍有降低, 因此用户可以主动使用其它方式获取类在运行时的全局环境. 例如, 对于HTML, 对界面类传递HTML元素而不仅仅是HTML元素的id值, 这样可以通过HTML元素自身获取全局环境. 这种方法应注意不同平台的兼容性问题. 代码例子如下,
清理函数![]() | ||
在当前(2006/7), 一些主流的ECMAScript实现系统 (如IE6及以下版本) 内部存在Bug. 主要表现为, 当多个对象间发生循环引用时, ECMAScript对象会发生无法释放的问题. ESOE引入清理函数/析构函数机制方案, 使用户可清除有可能发生的循环引用问题, 提高应用系统的实用性. 这个机制可通过引擎参数 _nodestroy关闭. ESOE的清理函数机制并不在变量的作用域失效后对变量进行清除, 而是在GLOBAL对象即将被卸载前由用户手工激活ESOE的清理机制, 例如对HTML/javascript, 在window.unload事件中调用$esoe.Destroy()即可激活ESOE的清理机制. ESOE要求清除的循环引用包括: 1. 与全局环境间的相互引用. 2. 与类库文件间的相互引用. 3. 共享ESOE引擎所引起的相互引用. 4. ESOE引擎内部的相互引用