编码规范

1 命名规范

以下为通用规则,适用于前端(JS代码), 后端(PHP代码),数据库设计(表/字段),接口定义等。

不同类型命名惯例:

在进行类型转型时,应特别注意区分,如

var startDt = parseDate(startDtStr); // startDt是日期类型,startDtStr是日期的格式化字符串
var total = parseFloat(totalStr);

2 代码结构与分区

一个文件内或复杂模块的代码按惯例划分为多个区域,可配合使用折叠以方便查阅。 优点:

文件级别常分为:

文件结构示例:

	// ====== config: 全局配置区 {{{
	var g_allowedEntries = []
	// }}}

	// ====== global: 全局变量区 {{{
	var g_data = {
		userInfo : null, // {uid, name, phone}
	};
	//}}}

	// ====== toolkit: 通用函数 {{{
	function each()
	{
	}
	// }}}

	// ====== app toolkit: 项目内各应用通用函数 {{{
	function setupPopup(jpopup, initfn)
	{
	}
	// }}}

	// ====== functions: 本应用使用的函数 {{{
	function logout()
	{
	}
	//}}}
			
	// ====== main: 初始化区域 {{{

	function main()
	{
	}

	// }}}

	// ====== 模块1 {{{
	// }}}

	// ====== 模块2 {{{
	// }}}

以上使用三个花括号配对来标识折叠,如使用vim编辑器,可通过设置 foldmethod=marker 来显示折叠。

模块(或复杂函数内部)常分为:

复杂模块结构示例:

function initPageOrder()
{
	var jpage = $(this);
	
	// 变量,事件绑定等初始化区域
	var orderId_;
	jpage.on("pagebeforeshow", onPageBeforeShow);

	// 函数区域
	function onPageBeforeShow(ev)
	{
	}
}

3 前端代码

3.1 JS编码规范

常用的通用变量名:

界面元素的命名(包括在DOM中指定id),应加类型前缀,定义如下:

jquery-mobile中常用类型前缀:

jquery-easyui中常用类型前缀:

jquery对象的命名:加前缀"j"或"$", 如jdlg, jpage, jchk, 通用对象一般用jo.

MyUI框架中使用的属性、css类,常加"my-"前缀,如

css类命名采用驼峰式,如"notForFind", 如果有前缀,用"-"分隔,常用前缀:

3.2 Jquery-mobile框架编码规范

设计目标:

约定:

page的DOM定义样例:

<div data-role="page" id="order">
	<div data-role="header">
	</div><!-- /header -->

	<div role="main" class="ui-content">
	</div><!-- /content -->
</div>

page的JS代码样例:

// 接口:供其它页面调用
var PageOrder = {
	/** @fn PageOrder.show(orderId) */
	show: function(orderId) {
		this.id_ = orderId;
		MUI.showPage("#order");
	}
	
	id_: null,
};

function initPageOrder()
{
	// 模块变量,事件绑定及初始化代码区域
	var jpage = $(this);
	var orderId_;
	
	jpage.on("pagebeforeshow", onPageBeforeShow);
	jpage.find("#btnCancelOrder", btnCancelOrder_click);

	function onPageBeforeShow(ev)
	{
		// show order PageOrder.m_id
		callSvr("Ordr.get", {id: PageOrder.id_}, api_OrdrGet);
		
		function api_OrdrGet(data)
		{
			orderId_ = data.id;
			showOrder();
		}
	}
	
	function btnCancelOrder_click(ev)
	{
		callSvr("cancelOrder", {id: orderId_}, api_cancelOrder);
		
		function api_cancelOrder(data)
		{
			app_alert("操作成功", "i", function () {
				showOrder();
			});
		}
	}
	
	function showOrder()
	{
	}
}

3.3 Jquery-easyui/MyUI编码规范

主要约定: 同一模块的相关对象(页面page, 数据表tbl, 对话框dlg)使用统一的命名,如订单模块(Order):

再如结算模块(CloseOrder), 应该用名称:页面pageCloseOrder (页面初始化initPageCloseOrder), 对象框dlgCloseOrder等。

page的DOM定义样例:

<div id="my-pages" style="display:none">
	...
	<div class="pageOrder" title="订单管理" my-initfn="initPageOrder">
		<table id="tblOrder" style="width:auto;height:auto">
			<thead><tr>
				<th data-options="field:'id', sortable:true, sorter:intSort">订单号</th>
			</tr></thead>
		</table>
	</div>
	
	<div id="dlgOrder" my-obj="Ordr" my-initfn="initDlgOrder" title="用户订单" style="padding:20px 40px 20px 40px;width:520px;height:500px;">  
		<form method="POST">
			<table>
				<tr>
					<td>订单号</td>
					<td><input name="id" disabled></td>
				</tr>
			</table>
		</form>
	</div>
	...
</div>

page及dialog的JS代码样例:

function initPageOrder() 
{
	var jpage = $(this);
	var jtbl = jpage.find("#tblOrder");
	var jdlg = $("#dlgOrder");
	...
}

function initDlgOrder()
{
	var jdlg = $(this);
	var jfrm = jdlg.find("form");
	...
}

4 后端代码

后端API框架强制要求:

4.1 命名

在应用中, 对于模块, 一般应考虑用类实现(如class Conf), 这样便于隐藏内部实现函数;

在框架实现中, 增加以下要求: 对于框架(如app_fw, api_fw)模块, 因为类接口如ApiFw::param 或 命名空间如ApiFw\param使用麻烦, 所以基本只用函数接口(如param, 加/** @fn */标注接口). 这样框架的内部实现则放入内部类, 一般用下划线结尾标识, 如"class AppFw_". (对于应用此要求仅供参考.)

例:

const T_HOUR = 3600; // 全局常量

global TEST_MODE; // 全局变量, 使用全部大写, 表示在初始化后当作常量使用; 
// 使用global声明, 好处是即使在函数中被include, 也仍然是全局变量.

global g_dbgInfo; // 全局变量. 使用时应加global声明, 或用$GLOBALS["g_dbgInfo"]
g_dbgInfo = [];

class AppFw_  // 内部类, 与模块同名表示模块实现部分
{
	const C = 1; // 模块内部常量
	static $SOLO; // 模块内部全局变量, 初始化后当常量使用
	static $var; // 模块内部全局变量
	
	// 模块私有函数
	private static function initGlobals() {}
	// 模块内部接口函数
	static function init();
}

// 模块内私有函数, 一般不建议使用, 应考虑放入AppFw_类中.
function getParam_()
{
}

/** @fn param($name) */
// 接口函数
function param($name)
{
}

规定:

5 格式化注释

格式化注释用于描述接口,也可通过工具生成文档。

设计时主要参考doxygen, javadoc, jsdoc等流行工具,设计理念:

约定:

使用需知: 框架中的接口应使用规范的格式化注释,便于生成文档。 应用中的接口可简单标识,便于查询。

示例:


/** 
@fn MyUI.showPage(pageName, title?, paramArr?)
@param pageName 由page上的class指定。
@param title? 如果未指定,则使用page上的title属性.
@param paramArr? 调用initfn时使用的参数,是一个数组。

新页面以title作为id。
注意:每个页面都是根据pages下相应pageName复制出来的,显示在一个新的tab页中。相同的title当作同一页面。
初始化函数由page上的my-initfn属性指定。

page定义示例: 

	<div id="my-pages" style="display:none">
		<div class="pageHome" title="首页" my-initfn="initPageHome"></div>
	</div>

page调用示例:

	showPage("pageHome");
	showPage("pageHome", "首页");
	showPage("pageHome", "首页2");
*/
function showPage(pageName, title, paramArr)
{
}

参考: