HTML5/JavaScript 编程规范
一、文本编辑规则
缩进为2个空格,不使用tab
标签全部采用小写字母,如<input type="checkbox" checked>
函数和变量名称小写开头,中间采用骆驼命名法,如:getElementById(...)
类似宏的函数名称全部小写或大写,以下划线分割单词,如:extend_class__
类名称大写字母开头,如 function MyObject(...)
类中方法、变量按作用域不同,采用不同的命名规则。
发布的版本一定要注释掉console.log(...)
单行注释总是: /*...*/。多行注释总是:/**...*/。短注释用://
以//?开头的注释总是属于未完成的临时代码
给属性添加的注释://@attributeName
二、类中方法、变量命名规则
对外暴露的类名称以大写字母开头,如MapPoint
内部使用的类名称以双下划线__开头加大写字母,如__ViewPort
类的公有方法或属性、变量与函数和变量的命名规则相同,如:mapPoint.getDistance
类的私有方法或属性、变量,并且允许被其他内部类访问,以单下划线_加小写字母开头
类的外部不能直接访问的私有方法、变量,以双下划线__加小写字母开头,如:__salaryAmount
类的静态变量以大写字母开头,如:MapPoint.MaxRadius
三、一个JavaScript类模板
/*******************************************************************************
* h5.hs
* cheungmine
******************************************************************************/
// 包含其他js文件
usingScript("utils.js");
/*******************************************************************************
* $MyClassBase
* Place comments here
******************************************************************************/
function MyClassBase() {
//?TODO:
}
/*******************************************************************************
* $MyClass
* Place comments here
* 闭包:
* 这种公共、私有和特权成员的模式是可行的原因是由于JavaScript有closure闭包。
* 这意味着类中一个内部的函数总是可以访问这个函数外部的变量和参数,
* 甚至在外部的函数返回之后。这是这个语言的一个极其强大的特性。
* 私有和特权成员只能在对象构造的时候生成。
* 公共成员可以在任意时刻添加。
******************************************************************************/
// extend_class__ 声明 MyClass 继承自 MyClassBase
extend_class__(MyClass, MyClassBase);
function MyClass(/* 可以在此放置构造参数列表 */) {
// 另一种继承类的方法,可以提供不同的构造参数
// 不要与extend_class__同时使用
// MyClassBase.call(this);
/*************
* 私有成员:*
************/
// 可变参数示例,__args是严格私有变量
var __args=Array.prototype.slice.call(arguments);
var __salary = 0;
// 下面是一个私有方法示例,外部不能访问
function __parseArgs() {
self.__salary = 0;
if (__args.length>=2) {
this._family = __args[0];
this.name = __args[1];
if (__args.length==3)
self.__salary = __args[2];
return true;
}
return false;
}
/*************
* 特权成员:*
************/
// toString 提供类名称
this.toString = function () {
return "MyClassClass";
}
this.initialize = function (salary) {
if (salary!=null)
this.salaryAmount = salary;
return __parseArgs();
}
// 这是一个外部访问的公有方法,输出构造参数内容
this.printArgs = function () {
var i = 0;
for (i=0; i<__args.length; i++)
console.log(__args[i]);
}
/**
* 公共成员,但是因为加了下划线,说明我们本意不想被外部直接访问
* 但允许内部类访问
*/
this._family = null;
/**
* 公共成员,外部直接访问
*/
this.name = null;
/*************
* 特权属性: *
************/
//@valid
this.__defineGetter__("valid",
function () {
return (this._family!=null && this.name!=null);
}
);
//@salaryAmount
this.__defineSetter__("salaryAmount",
function (v) {
__salary=v*100;
}
);
/**
* 放在最后一行,self被内部方法使用
*/
var self = this;
}
// 下面是类静态变量的例子:
MyClass.prototype.DaysOfYear = 365;
/** * utils.js * cheungmine */ if(!getElem){ var getElem=(function(){ return function(id){ return document.getElementById(id); }; })(); } if(!includeScript){ var includeScript=(function(){ return function(js){ document.write('<script type="text/javascript" src="'+js+'"></script>'); }; })(); } if(!importScripts){ var importScripts=(function(globalEval){ var xhr=new XMLHttpRequest; return function importScripts(){ var args=Array.prototype.slice.call(arguments) ,len=args.length ,i=0 ,meta ,data ,content ; for(;i<len;i++){ if(args[i].substr(0,5).toLowerCase()==="data:"){ data=args[i]; content=data.indexOf(","); meta=data.substr(5,content).toLowerCase(); data=decodeURIComponent(data.substr(content+1)); if(/;\s*base64\s*[;,]/.test(meta)){ data=atob(data); } if(/;\s*charset=[uU][tT][fF]-?8\s*[;,]/.test(meta)){ data=decodeURIComponent(escape(data)); }}else{ xhr.open("GET",args[i],false); xhr.send(null); data=xhr.responseText; } globalEval(data); } }; }(eval)); } if(!usingScript){ var usingScript=(function(){ return function(js){ try{ includeScript(js); } catch(e){ importScripts(js); } }; })(); } if(!getBrowserAgent){ var getBrowserAgent=(function(){ return function(){ if ((navigator.userAgent.indexOf('MSIE')>=0)&&(navigator.userAgent.indexOf('Opera')<0)) return "$IE"; else if (navigator.userAgent.indexOf('Firefox')>=0) return "$FIREFOX"; else if (navigator.userAgent.indexOf('Opera')>=0) return "$OPERA"; else if (navigator.userAgent.indexOf('Chrome')>=0) return "$CHROME"; else return navigator.userAgent; }; })(); } if(!extend_class__){ var extend_class__=(function(){ return function(deriveClass, baseClass) { var base=new baseClass(); for (var m in base) { deriveClass.prototype[m]=base[m]; }}; })(); } if(!addEvent){ var addEvent=(function(){ if (document.addEventListener){ return function (el,type,fn){ if (el&&el.nodeName||el===window){ el.addEventListener(type,fn,false); }else if(el&&el.length){ for(var i=0;i<el.length;i++){ addEvent(el[i],type,fn); }}}; }else{ return function(el,type,fn){ if (el&&el.nodeName||el===window){ el.attachEvent('on'+type,function(){return fn.call(el,window.event);}); }else if(el&&el.length){ for(var i=0;i<el.length;i++){ addEvent(el[i],type,fn); }}}; }})(); } HTML5模板:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="author" content="cheungmine"> <title>The HTML5 Test Page</title> <!-- <link rel="stylesheet" href="css/styles.css?v=1.0"> --> <script src="utils.js"></script> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <script type="text/javascript"> console.log("run script in head"); var browser = getBrowserAgent(); addEvent(window, 'load', function () { if (browser=="$IE"||browser=="{1}quot;) { if (window.confirm("IE does not support HTML5 currently.\n"+ "please use lastest FireFox, Chrome or Opera!\n"+ "if you havenot any of them installed,\n"+ "please click OK to enter download page.")) { window.location.replace("selbrowser.html"); } else { window.close(); } } init(); } ); function init () { console.log("init after page load"); } </script> </head> <body> <header> <nav>HTML5/JavaScript 编程规范</nav> <p>(open me in Chrome and press F12 to switch debugging)</p> </header> <div id="main"> </div><!-- #main --> <!-- import js at bottom of body --> <script src="h5.js"></script> <script type="text/javascript"> console.log("run script in body"); var myCls = new MyClass("cheung", "mine"); myCls.printArgs(); myCls.initialize(250); console.log(myCls.DaysOfYear); </script> </body> </html>
/** * utils.js * cheungmine */ if(!getElem){ var getElem=(function(){ return function(id){ return document.getElementById(id); }; })(); } if(!includeScript){ var includeScript=(function(){ return function(js){ document.write('<script type="text/javascript" src="'+js+'"></script>'); }; })(); } if(!importScripts){ var importScripts=(function(globalEval){ var xhr=new XMLHttpRequest; return function importScripts(){ var args=Array.prototype.slice.call(arguments) ,len=args.length ,i=0 ,meta ,data ,content ; for(;i<len;i++){ if(args[i].substr(0,5).toLowerCase()==="data:"){ data=args[i]; content=data.indexOf(","); meta=data.substr(5,content).toLowerCase(); data=decodeURIComponent(data.substr(content+1)); if(/;\s*base64\s*[;,]/.test(meta)){ data=atob(data); } if(/;\s*charset=[uU][tT][fF]-?8\s*[;,]/.test(meta)){ data=decodeURIComponent(escape(data)); }}else{ xhr.open("GET",args[i],false); xhr.send(null); data=xhr.responseText; } globalEval(data); } }; }(eval)); } if(!usingScript){ var usingScript=(function(){ return function(js){ try{ includeScript(js); } catch(e){ importScripts(js); } }; })(); } if(!getBrowserAgent){ var getBrowserAgent=(function(){ return function(){ if ((navigator.userAgent.indexOf('MSIE')>=0)&&(navigator.userAgent.indexOf('Opera')<0)) return "$IE"; else if (navigator.userAgent.indexOf('Firefox')>=0) return "$FIREFOX"; else if (navigator.userAgent.indexOf('Opera')>=0) return "$OPERA"; else if (navigator.userAgent.indexOf('Chrome')>=0) return "$CHROME"; else return navigator.userAgent; }; })(); } if(!extend_class__){ var extend_class__=(function(){ return function(deriveClass, baseClass) { var base=new baseClass(); for (var m in base) { deriveClass.prototype[m]=base[m]; }}; })(); } if(!addEvent){ var addEvent=(function(){ if (document.addEventListener){ return function (el,type,fn){ if (el&&el.nodeName||el===window){ el.addEventListener(type,fn,false); }else if(el&&el.length){ for(var i=0;i<el.length;i++){ addEvent(el[i],type,fn); }}}; }else{ return function(el,type,fn){ if (el&&el.nodeName||el===window){ el.attachEvent('on'+type,function(){return fn.call(el,window.event);}); }else if(el&&el.length){ for(var i=0;i<el.length;i++){ addEvent(el[i],type,fn); }}}; }})(); } HTML5模板:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="author" content="cheungmine"> <title>The HTML5 Test Page</title> <!-- <link rel="stylesheet" href="css/styles.css?v=1.0"> --> <script src="utils.js"></script> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <script type="text/javascript"> console.log("run script in head"); var browser = getBrowserAgent(); addEvent(window, 'load', function () { if (browser=="$IE"||browser=="{1}quot;) { if (window.confirm("IE does not support HTML5 currently.\n"+ "please use lastest FireFox, Chrome or Opera!\n"+ "if you havenot any of them installed,\n"+ "please click OK to enter download page.")) { window.location.replace("selbrowser.html"); } else { window.close(); } } init(); } ); function init () { console.log("init after page load"); } </script> </head> <body> <header> <nav>HTML5/JavaScript 编程规范</nav> <p>(open me in Chrome and press F12 to switch debugging)</p> </header> <div id="main"> </div><!-- #main --> <!-- import js at bottom of body --> <script src="h5.js"></script> <script type="text/javascript"> console.log("run script in body"); var myCls = new MyClass("cheung", "mine"); myCls.printArgs(); myCls.initialize(250); console.log(myCls.DaysOfYear); </script> </body> </html>