總體規(guī)范
switch 下的 case 和 default 必須增加一個縮進層級
-
二元運算符兩側(cè)必須有一個空格讨彼,一元運算符與操作對象之間不允許有空格
var a = !arr.length; a++; a = b + c;
用作代碼塊起始的左花括號
{
前必須有一個空格if / else / for / while / function / switch / do / try / catch / finally
關(guān)鍵字后蔗蹋,必須有一個空格-
在對象創(chuàng)建時,屬性中的
:
之后必須有空格吹害,:
之前不允許有空格var obj = { a: 1, b: 2, c: 3 }; // bad var obj = { a : 1, b:2, c :3 };
函數(shù)聲明兔跌、具名函數(shù)表達式座享、函數(shù)調(diào)用中,函數(shù)名和
(
之間不允許有空格,
和;
前不允許有空格-
在函數(shù)調(diào)用龄减、函數(shù)聲明项钮、括號表達式、屬性訪問希停、if / for / while / switch / catch 等語句中烁巫,() 和 [] 內(nèi)緊貼括號部分不允許有空格
// good callFunc(param1, param2, param3); save(this.list[this.indexes[i]]); needIncream && (variable += increament); if (num > list.length) { } while (len--) { } // bad callFunc( param1, param2, param3 ); save( this.list[ this.indexes[ i ] ] ); needIncreament && ( variable += increament ); if ( num > list.length ) { } while ( len-- ) { }
單行聲明的數(shù)組與對象,如果包含元素宠能,
{}
和[]
內(nèi)緊貼括號部分不允許包含空格行尾不得有多余的空格
-
運算符處換行時劲够,運算符必須在新行的行首
// good if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin') ) { // Code } var result = number1 + number2 + number3 + number4 + number5; // bad if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin')) { // Code } var result = number1 + number2 + number3 + number4 + number5;
-
在函數(shù)聲明余舶、函數(shù)表達式、函數(shù)調(diào)用、對象創(chuàng)建江咳、數(shù)組創(chuàng)建、for語句等場景中,不允許在
,
或;
前換行// good var obj = { a: 1, b: 2, c: 3 }; foo( aVeryVeryLongArgument, anotherVeryLongArgument, callback ); // bad var obj = { a: 1 , b: 2 , c: 3 }; foo( aVeryVeryLongArgument , anotherVeryLongArgument , callback );
不同行為或邏輯的語句集,使用空行隔開脾还,更易閱讀
較復雜的邏輯條件組合,將每個條件獨立一行入愧,邏輯運算符放置在行首進行分隔荠呐,或?qū)⒉糠诌壿嫲催壿嫿M合進行分隔。
-
建議最終將右括號
)
與左大括號{
放在獨立一行砂客,保證與 if 內(nèi)語句塊能容易視覺辨識。if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin') ) { // Code }
按一定長度截斷字符串呵恢,并使用 + 運算符進行連接鞠值。
分隔字符串盡量按語義進行,如不要在一個完整的名詞中間斷開渗钉。
-
特別的彤恶,對于HTML片段的拼接,通過縮進鳄橘,保持和HTML相同的結(jié)構(gòu)声离。
也可使用數(shù)組來進行拼接,相對 + 更容易調(diào)整縮進瘫怜。var html = [ '<article>', '<h1>Title here</h1>', '<p>This is a paragraph</p>', '<footer>Complete</footer>', '</article>' ]; html = html.join('');
當參數(shù)過多時术徊,將每個參數(shù)獨立寫在一行上,并將結(jié)束的右括號
)
獨立一行鲸湃。-
所有參數(shù)必須增加一個縮進赠涮。
foo( aVeryVeryLongArgument, anotherVeryLongArgument, callback );
也可以按邏輯對參數(shù)進行組合。
最經(jīng)典的是baidu.format
函數(shù)暗挑,調(diào)用時將參數(shù)分為“模板”和“數(shù)據(jù)”兩塊
baidu.format(
dateFormatTemplate,
year, month, date, hour, minute, second
);
當函數(shù)調(diào)用時笋除,如果有一個或以上參數(shù)跨越多行,應當每一個參數(shù)獨立一行炸裆。
這通常出現(xiàn)在匿名函數(shù)或者對象初始化等作為參數(shù)時垃它,如setTimeout
函數(shù)等。
setTimeout(
function () {
alert('hello');
},
200
);
order.data.read(
'id=' + me.model.id,
function (data) {
me.attchToModel(data.result);
callback();
},
300
);
-
鏈式調(diào)用較長時采用縮進進行調(diào)整烹看。
$('#items') .find('.selected') .highlight() .end();
-
三元運算符由3部分組成国拇,因此其換行應當根據(jù)每個部分的長度不同,形成不同的情況惯殊。
var result = thisIsAVeryVeryLongCondition ? resultA : resultB; var result = condition ? thisIsAVeryVeryLongResult : resultB;
-
數(shù)組和對象初始化的混用贝奇,嚴格按照每個對象的 { 和結(jié)束 } 在獨立一行的風格書寫。
var array = [ { // ... }, { // ... } ];
對于 if...else...
靠胜、try...catch...finally
等語句掉瞳,推薦使用在}
號后添加一個換行 的風格毕源,使代碼層次結(jié)構(gòu)更清晰,閱讀性更好陕习。
不得省略語句結(jié)束的分號
在 if / else / for / do / while 語句中霎褐,即使只有一行,也不得省略塊{...}
函數(shù)定義結(jié)束不允許添加分號
IIFE 必須在函數(shù)表達式外添加 (该镣,非 IIFE 不得在函數(shù)表達式外添加 (
額外的 ( 能夠讓代碼在閱讀的一開始就能判斷函數(shù)是否立即被調(diào)用冻璃,進而明白接下來代碼的用途。而不是一直拖到底部才恍然大悟损合。
命名
變量 使用 Camel命名法
常量 使用 全部字母大寫省艳,單詞間下劃線分隔 的命名方式
-
類 使用 Pascal命名法
function TextNode(options) { }
-
類的 方法 / 屬性 使用 Camel命名法
function TextNode(value, engine) { this.value = value; this.engine = engine; } TextNode.prototype.clone = function () { return this; }
枚舉變量 使用 Pascal命名法,枚舉的屬性 使用 全部字母大寫嫁审,單詞間下劃線分隔 的命名方式
由多個單詞組成的縮寫詞跋炕,在命名中,根據(jù)當前命名法和出現(xiàn)的位置律适,所有字母的大小寫與首字母的大小寫保持一致辐烂。
-
由多個單詞組成的縮寫詞,在命名中捂贿,根據(jù)當前命名法和出現(xiàn)的位置纠修,所有字母的大小寫與首字母的大小寫保持一致
function XMLParser() { } function insertHTML(element, html) { } var httpRequest = new HTTPRequest();
類名 使用 名詞
函數(shù)名 使用 動賓短語
boolean 類型的變量使用 is 或 has 開頭
-
Promise對象 用 動賓短語的進行時 表達
var loadingData = ajax.get('url'); loadingData.then(callback);
注釋
單行注釋
必須獨占一行。// 后跟一個空格厂僧,縮進與下一行被注釋說明的代碼一致扣草。多行注釋
避免使用 /.../ 這樣的多行注釋。有多行注釋內(nèi)容時颜屠,使用多個單行注釋-
文檔化注釋
為了便于代碼閱讀和自文檔化德召,以下內(nèi)容必須包含以 /*.../ 形式的塊注釋中文檔注釋前必須空一行
自文檔化的文檔說明 what,而不是 how 文件頂部必須包含文件注釋汽纤,用 @file 標識文件說明
文件注釋中可以用 @author 標識開發(fā)者信息命名空間使用 @namespace 標識上岗。
示例:
/**
* @namespace
*/
var util = {};
類和構(gòu)造函數(shù)
- 使用 @class 標記類或構(gòu)造函數(shù)。
解釋:
對于使用對象 constructor 屬性來定義的構(gòu)造函數(shù)蕴坪,可以使用 @constructor 來標記肴掷。
示例:
/**
* 描述
*
* @class
*/
function Developer() {
// constructor body
}
- 使用 @extends 標記類的繼承信息。
示例:
/**
* 描述
*
* @class
* @extends Developer
*/
function Fronteer() {
Developer.call(this);
// constructor body
}
util.inherits(Fronteer, Developer);
- 使用包裝方式擴展類成員時背传, 必須通過 @lends 進行重新指向.沒有 @lends 標記將無法為該類生成包含擴展類成員的文檔呆瞻。
示例:
/**
* 類描述
*
* @class
* @extends Developer
*/
function Fronteer() {
Developer.call(this);
// constructor body
}
util.extend(
Fronteer.prototype,
/** @lends Fronteer.prototype */{
_getLevel: function () {
// TODO
}
}
);
- 類的屬性或方法等成員信息使用 @public / @protected / @private 中的任意一個,指明可訪問性径玖。
解釋:
生成的文檔中將有可訪問性的標記痴脾,避免用戶直接使用非 public 的屬性或方法。
示例:
/**
* 類描述
*
* @class
* @extends Developer
*/
var Fronteer = function () {
Developer.call(this);
/**
* 屬性描述
*
* @type {string}
* @private
*/
this._level = 'T12';
// constructor body
};
util.inherits(Fronteer, Developer);
/**
* 方法描述
*
* @private
* @return {string} 返回值描述
*/
Fronteer.prototype._getLevel = function () {
};
函數(shù)/方法注釋
函數(shù)/方法注釋必須包含函數(shù)說明梳星,有參數(shù)和返回值時必須使用注釋標識
參數(shù)和返回值注釋必須包含類型信息和說明
// null 或 undefined
// good
if (noValue == null) {
// ......
}
// bad
if (noValue === null || typeof noValue === 'undefined') {
// ......
}
如果函數(shù)或全局中的 else 塊后沒有任何語句赞赖,可以刪除 else滚朵。
// good
function getName() {
if (name) {
return name;
}
return 'unnamed';
}
// bad
function getName() {
if (name) {
return name;
}
else {
return 'unnamed';
}
}
對循環(huán)內(nèi)多次使用的不變值,在循環(huán)外用變量緩存
// good
var width = wrap.offsetWidth + 'px';
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
element.style.width = width;
// ......
}
// bad
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
element.style.width = wrap.offsetWidth + 'px';
// ......
}
對有序集合進行順序無關(guān)的遍歷時前域,使用逆序遍歷辕近。
解釋:
逆序遍歷可以節(jié)省變量,代碼比較優(yōu)化匿垄。
示例:
var len = elements.length;
while (len--) {
var element = elements[len];
// ......
}
類型轉(zhuǎn)換檢測
類型檢測優(yōu)先使用
typeof
移宅。對象類型檢測使用instanceof
。null
或undefined
的檢測使用== null
轉(zhuǎn)換成 string 時椿疗,使用 + ''漏峰。
示例:
// good
num + '';
// bad
new String(num);
num.toString();
String(num);
- 轉(zhuǎn)換成 number 時,通常使用 +届榄。
示例:
// good
+str;
// bad
Number(str);
- string 轉(zhuǎn)換成 number浅乔,要轉(zhuǎn)換的字符串結(jié)尾包含非數(shù)字并期望忽略時,使用 parseInt痒蓬。
示例:
var width = '200px';
parseInt(width, 10);
- 使用 parseInt 時,必須指定進制滴劲。
示例:
// good
parseInt(str, 10);
// bad
parseInt(str);
- 轉(zhuǎn)換成 boolean 時攻晒,使用 !!。
示例:
var num = 3.14;
!!num;
- number 去除小數(shù)點班挖,使用 Math.floor / Math.round / Math.ceil鲁捏,不使用 parseInt。
示例:
// good
var num = 3.14;
Math.ceil(num);
// bad
var num = 3.14;
parseInt(num, 10);
字符串
-
字符串開頭和結(jié)束使用單引號 '萧芙。
解釋:
輸入單引號不需要按住 shift给梅,方便輸入。
實際使用中双揪,字符串經(jīng)常用來拼接 HTML动羽。為方便 HTML 中包含雙引號而不需要轉(zhuǎn)義寫法。
示例:var str = '我是一個字符串'; var html = '<div class="cls">拼接HTML可以省去雙引號轉(zhuǎn)義</div>';
-
使用 數(shù)組 或 + 拼接字符串渔期。
解釋:
使用 + 拼接字符串运吓,如果拼接的全部是 StringLiteral,壓縮工具可以對其進行自動合并的優(yōu)化疯趟。所以拘哨,靜態(tài)字符串建議使用 + 拼接。
在現(xiàn)代瀏覽器下信峻,使用 + 拼接字符串倦青,性能較數(shù)組的方式要高。
如需要兼顧老舊瀏覽器盹舞,應盡量使用數(shù)組拼接字符串产镐。
示例:// 使用數(shù)組拼接字符串 var str = [ // 推薦換行開始并縮進開始第一個字符串, 對齊代碼, 方便閱讀. '<ul>', '<li>第一項</li>', '<li>第二項</li>', '</ul>' ].join(''); // 使用 + 拼接字符串 var str2 = '' // 建議第一個為空字符串, 第二個換行開始并縮進開始, 對齊代碼, 方便閱讀 + '<ul>', + '<li>第一項</li>', + '<li>第二項</li>', + '</ul>';
對象
- 使用對象字面量 {} 創(chuàng)建新 Object隘庄。
示例:
// good
var obj = {};
// bad
var obj = new Object();
- 對象創(chuàng)建時,如果一個對象的所有 屬性 均可以不添加引號磷账,則所有 屬性 不得添加引號峭沦。
示例:
var info = {
name: 'someone',
age: 28
};
- 對象創(chuàng)建時,如果任何一個 屬性 需要添加引號逃糟,則所有 屬性 必須添加 '吼鱼。
解釋:
如果屬性不符合 Identifier 和 NumberLiteral 的形式,就需要以 StringLiteral 的形式提供绰咽。
示例:
// good
var info = {
'name': 'someone',
'age': 28,
'more-info': '...'
};
// bad
var info = {
name: 'someone',
age: 28,
'more-info': '...'
};
- 不允許修改和擴展任何原生對象和宿主對象的原型菇肃。
示例:
// 以下行為絕對禁止
String.prototype.trim = function () {
};
屬性訪問時,盡量使用
.
取募。
解釋:
屬性名符合 Identifier 的要求琐谤,就可以通過 . 來訪問,否則就只能通過 [expr] 方式訪問玩敏。通常在 JavaScript 中聲明的對象斗忌,屬性命名是使用 Camel 命名法,用 . 來訪問更清晰簡潔旺聚。部分特殊的屬性(比如來自后端的JSON)织阳,可能采用不尋常的命名方式,可以通過 [expr] 方式訪問砰粹。
示例:
info.age;
info['more-info'];
- for in 遍歷對象時, 使用 hasOwnProperty 過濾掉原型中的屬性唧躲。
示例:
var newInfo = {};
for (var key in info) {
if (info.hasOwnProperty(key)) {
newInfo[key] = info[key];
}
}
數(shù)組
使用數(shù)組字面量[]
創(chuàng)建新數(shù)組,除非想要創(chuàng)建的是指定長度的數(shù)組碱璃。
示例:
// good
var arr = [];
// bad
var arr = new Array();
- 遍歷數(shù)組不使用 for in弄痹。
解釋:
數(shù)組對象可能存在數(shù)字以外的屬性, 這種情況下 for in 不會得到正確結(jié)果.
示例:
var arr = ['a', 'b', 'c'];
arr.other = 'other things'; // 這里僅作演示, 實際中應使用Object類型
// 正確的遍歷方式
for (var i = 0, len = arr.length; i < len; i++) {
console.log(i);
}
// 錯誤的遍歷方式
for (i in arr) {
console.log(i);
}
不因為性能的原因自己實現(xiàn)數(shù)組排序功能,盡量使用數(shù)組的 sort 方法嵌器。
解釋:
自己實現(xiàn)的常規(guī)排序算法肛真,在性能上并不優(yōu)于數(shù)組默認的 sort 方法。以下兩種場景可以自己實現(xiàn)排序:需要穩(wěn)定的排序算法爽航,達到嚴格一致的排序結(jié)果毁欣。
數(shù)據(jù)特點鮮明,適合使用桶排岳掐。清空數(shù)組使用 .length = 0凭疮。
函數(shù)
一個函數(shù)的長度控制在 50 行以內(nèi)。
解釋:
將過多的邏輯單元混在一個大函數(shù)中串述,易導致難以維護执解。一個清晰易懂的函數(shù)應該完成單一的邏輯單元。復雜的操作應進一步抽取,通過函數(shù)的調(diào)用來體現(xiàn)流程衰腌。特定算法等不可分割的邏輯允許例外新蟆。
一個函數(shù)的參數(shù)控制在 6 個以內(nèi)。
解釋:
除去不定長參數(shù)以外右蕊,函數(shù)具備不同邏輯意義的參數(shù)建議控制在 6 個以內(nèi)琼稻,過多參數(shù)會導致維護難度增大。某些情況下帕翻,如使用 AMD Loader 的 require 加載多個模塊時嘀掸,其 callback 可能會存在較多參數(shù)睬塌,因此對函數(shù)參數(shù)的個數(shù)不做強制限制歇万。
空函數(shù)不使用 new Function() 的形式贪磺。
示例:
var emptyFunction = function () {};
- 對于性能有高要求的場合,建議存在一個空函數(shù)的常量瞄崇,供多處使用共享。
示例:
var EMPTY_FUNCTION = function () {};
function MyClass() {
}
MyClass.prototype.abstractMethod = EMPTY_FUNCTION;
MyClass.prototype.hooks.before = EMPTY_FUNCTION;
MyClass.prototype.hooks.after = EMPTY_FUNCTION;
元素樣式style
盡可能通過為元素添加預定義的 className 來改變元素樣式腮郊,避免直接操作 style 設置
通過 style 對象設置元素樣式時轧飞,對于帶單位非 0 值的屬性撒踪,不允許省略單位
之前寫的筆記制妄,想要再找原文耕捞,找不到了烫幕。较曼。只是知識的搬運工捷犹。