Qomo项目中代码的一般性约定

    技术2022-05-11  72

     ================================================================================Qomolangma OpenProject v1.0

    类别    :Rich Web Client关键词  :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component,          DOM,DTHML,CSS,JavaScript,JScript

    项目发起:aimingoo (aim@263.net)项目团队:../../Qomo_team.txt================================================================================

    一、变量声明的一般性方法~~~~~~~~~~~~~~~~~~Qomo约定在全局空间进行变量声明时,应用var关键字来声明,而不应当省略(尽管语法上讲能这样做)。声明时的代码格式尽可能使用如下形式:------------------var  v1 = 1234;  v2 = 'abcd';------------------或为每行声明都保留var关键字,例如:------------------var v1 = 1234;var v2 = 'abcd';------------------

    Qomo约定在函数内部声明局部变量进,使用var关键字时可以用如下省写形式:------------------var  v1 = 1234,      // <-- 注意行未是逗号  v2 = 'abcd';------------------或为每行声明保留var关键字。

    Qomo反对在函数内部声明全局变量。

     

    二、Qomo中一些保留的命名~~~~~~~~~~~~~~~~~~Qomo会将一些实现特殊的、具有“关键字”性质的功能声明为全局函数。它们通常具有特殊的名字,而且是以大写字符开始的(这看起来有点象构造器,但并不是)。这些函数名部分看起来象JavaScript的保留字,但由于javascript的命名是大小写区分的,且保留字都使用小写字符,因此这并不冲突。这些全局函数有:------------------  Class()        : 注册类  Attribute()    : 快速属性声明  Interface()    : 接口声明  Aggregate()    : 接口聚合  Abstract()     : 抽象方法  NullFunction() : 空函数/空方法------------------

    Qomo为构建系统框架,使用标准的JS原型继承的方式在全局范围内声明了一些类(构造器),用户代码应该避免覆盖这些名称。这些命名包括:------------------  Url()             : 分析一个Url地址  Ajax()            : Ajax异步方式  MuEvent()         : 多投事件  CustomArguments() : 标识函数入口使用了定制参数  BreakEventCast()  : 标识事件投送列表被中止  JoPoint()         : 切面系统中的连接点  JoPoints()        : 切面系统中的连接点列表  Profilers()       : 创建系统分析对象------------------

    作为习惯,Qomo保留了一些(少量的)全局的工具函数,例如:------------------  format()             : 指向String.format();  RegisterInterface()  : 指向Interface.RegisterInterface()  QueryInterface()     : 指向Interface.QueryInterface()

      isAlias()            : 检测一个命名空间是否是别名  isNamespace()        : 检测一个变量是否是命名空间声明

      getAllFunctions()    : (用于调试与性能分析,) 列出一个代码块中调用过的函数与方法  showProfiler()       : (用于调试与性能分析,) 调用$debug来显示性能分析报告------------------

    除了上述三种情况,Qomo中将尽可能少的占用全局的命名,例如函数或变量。

    为此,Qomo为开发人员准备了一份资料文档,用于通告哪那些全局函数、类与命名空间被使用了,开发人员应尽可能避免出现相冲突的命名。

     

    三、Qomo中的一些命名约定~~~~~~~~~~~~~~~~~~1. 系统的特殊声明==============Qomo约定以$开始的变量为系统特殊的声明,它通常是关键的函数或可能在系统编译时被特殊处理的函数。这些函数主要包括:------------------  $import() : 导入文件或包  $inline() : 内联代码块  $assert() : 断言  $debug()  : 调试输出

      $map()    : 创建命名与路径的映射  $mapx()   : 展开命名空间  $n2p()    : 命名空间到路径的转换  $p2n()    : 路径到命名空间的转换

      $profilers : (对象)全局的性能分析器

      $Q() : 等同于$QomoConfig  $QomoConfig() : 查询Qomo装载时或编译时的配置信息  $QomoCoreFunction : 简单地返回一个函数用来替换Function对象的toString()方法,以保护代码------------------此外,一些函数内的局部变量也使用$来表明它的特殊性。

    Qomo约定以"_"开始的函数具有使用的上下文环境限制。主要包括:------------------// 以下函数仅能在类声明中使用//  - 注: Attribute()也仅能在类声明使用  _cls : 取类引用  _get : 类内部信息的getter  _set : 类内部信息的setter------------------此外,一些函数内的局部变量也使用_来表明它的特殊性,或与一个没有该前缀的同名函数存在关联。

    Qomo约定全大写的变量是系统保留的,或有特殊的含义的变量,该规则并不限于在函数内/外使用。例如:------------------  _RTLOBJECT : 在Qomo替换之前的Object()构造器  _RTLERROR  : 在Qomo替换之前的Error()构造器------------------

     

    2. 异常==============Qomo约定以字符“E”开始并紧邻一个大写字母表明一个异常。异常可以用数组形式来表示,例如:------------------  ECallClassBadArguments = [8101, 'Arguments error  for Class().'];  ERegClassNoname = [8102, 'With call Class(), lost class name .'];  EAccessSafeArea = [8104, 'Try Access Safe area.'];------------------

     

    3. 类与类类型注册==============Qomo约定以大写字母开始的函数通常是类构造器,而以小写字母开始的函数是普通函数或方法。这一点是JavaScript惯用的代码风格。例如:------------------  // 类构造器  function MyObject() {    // ..  }

      // 方法或函数  function callSafeMethod() {    // ..  }------------------

    Qomo约定应当以字符“T”开始,后面紧跟构造器函数名的格式对一个类进行类注册。Qomo的OOP系统和命名空间系统依赖于类注册。类注册使用Class()函数。例如:------------------  // 类构造器声明  function MyObject() {    // ...  }

      // 类注册  TMyObject = Class(Object, 'MyObject');------------------

     

    4. 事件、事件句柄与事件类型==============Qomo约定以On开始的属性为事件,而以do开始的函数通常用作事件句柄。例如:------------------  function doCall() {    // ...  }

      function MyObject() {    this.OnCall = NullFunction;  }

      var obj = new MyObject();  obj.OnCall.add(doCall);------------------

    Qomo约定事件可以用一个函数声明来描述事件的接口,但这个声明除了便于开发人员使用之外,并没有任何价值。一般情况下,该声明应该以字符“T”起始,紧接事件名,最后可以用Event结束。例如:------------------  TOnCall = function(item, index) { }  TOnLoadEvent = function(filename, filenum) { }

      function MyObject() {    this.OnCall = TOnCall;    this.OnLoad = TOnLoadEvent;  }------------------对于上面的声明来说,OnCall与OnLoad后面是一个空函数(NullFunction)还是一个事件类型的声明并没有关系。上面这样做,只是便于开发人员理解:当事件发生时,事件句柄可以得到怎样的入口数据。

    由于“事件类型”只有声明和描述的价值,它事实上从来不会被执行。因此,可以在不同的文件中,或者相同文件的不同类、不同位置重复的声明相同名字的“事件类型”。这对程序执行不会有负面的影响。

     

    5. 接口==============Qomo约定接口是以“I”字符开始来声明一个函数。接口的方法应声明为Abstract。例如:------------------  IInterface = function() {    this.QueryInterface = Abstract;  }------------------

     

    6. 切面==============Qomo约定应尽量以asp或asp_为前缀来声明切面。例如:------------------  var asp_OnTimer = new ObjectAspect(T2, 'OnTimer', 'Event', x0);  var asp_getTopoString = new FunctionAspect(getTopoString, 'getTopoString', 'Function');------------------

     

    7. 内联代码==============使用$inline()可以将一个代码片断内联到当前位置执行。Qomo约定被联接的代码块应该是一个独立的文件,文件中可以包括注释,其代码体应该被包含在一个标签声明当中。这个标签声明只用于表现该代码块的特殊性,实际上没有执行价值。

    该标签声明应当以“_inline_”为前缀。例如:------------------/** * * 内联代码可以按JS的语言规范任意包含注释 * */_inline_object_regAllInterfaceForClass: {

        // register interfaces for Class's all instnaces    if (arguments.length > 2) {      Interface.RegisterInterface.apply(cls, [cls].concat(        Array.prototype.slice.call(arguments, 2)      ))    }

    }------------------

    8. 字符串、数组、正则等使用中的一般性规则==============Qomo约定尽可能以单引号来声明字符串,而将双引号留给HTML中的属性来使用。

    Qomo约定以如果在全局使用正则表达式,应该以“_r_”为前缀声明,在函数局部使用正则表达式,应尽可能使用该规则。例如:------------------  _r_event = /^On.+/;  _r_attribute = /^([gs]et)(.+)/;------------------

    JavaScript中常用数组来表达一张表格,Qomo建议这种情况下的代码应该写成如下格式:------------------var aTable = [ [v1, v2, v3,                   v4], [v1, v2, v3,                   v4], [v1, v2, this_is_long_variant, v4], [v1, v2, v3,                   v4]   // <-- 注意最后一行没有","号];------------------尽可能用对齐的方式来避免表格修改时导致的出错。

     

    四、Qomo中的一些特殊使用法~~~~~~~~~~~~~~~~~~1. 对象(Object)的特殊用法==============Qomo直接替换了构造器Object(),因此使用new Object()的方式会构造出一个Qomo格式的对象实例。但用户代码中仍然可以通过直接量声明来得到一个“原生的”JavaScript对象。例如:------------------var  obj_1 = new Object();   // Qomo对象  obj_2 = { };            // JavaScript原生的、直接量声明的对象------------------二者的区别在于,obj_1因为是Qomo对象,因此必然具有如下方法和属性:------------------  obj_1.ClassInfo  obj_1.get()  obj_1.set()  obj_1.inherited()------------------而obj_2由于是原生的JavaScript对象,因此使用for .. in来列举时,不会看到任何“显式的”属性与方法。

    Qomo约定用户代码不应当修改直接量形式所得到的Object的原型(prototype)。由于这种对象没有任何“显式的”属性与方法,因此它可以用来做for ..  in做一些高速的列表处理。部分内核代码使用了这种特性。

    ——在firefox等mozilla引擎中,对替换后的Object()进行原型修改会污染(我并不确定这是否更加规范)原生的、直接量声明的对象。因此本项“特殊用法”应当谨慎使用。

     

    10. 匿名函数的特殊使用法==============为了避免一段代码占用全局空间中的名称(命名污染),通常会使用匿名函数来执行一段代码。Qomo建议这种情况下使用void来触发该匿名函数的执行。——而不是使用一对括号来做相同的事。例如:------------------// 推荐用法void function() {  // 你的代码...}();

    // 不推荐用法(function() {  // 你的代码...})();------------------

    如果执行的结果会返回值,例如声明一个变量。则建议使用如下的结构:------------------var myFunc = function() {  // 一些私有变量的声明  var ...

      // 你的函数  var _myFunc = function() {    //...  }

      // 返回  return _myFunc;}();------------------

    如果不对上述的_myFunc做特殊处理(例如添加属性),那么上述的代码可以简化至:------------------var myFunc = function() {  // 一些私有变量的声明  var ...

      // 返回你的函数  return function() {    //...  }}();------------------


    最新回复(0)