前端團(tuán)隊(duì)開發(fā)規(guī)范

開發(fā)工具

【強(qiáng)制】使用Visual Studio Code 【強(qiáng)制】手腳架 umi.js

注釋規(guī)范

【強(qiáng)制】邏輯代碼塊超過5行必須給注釋說明;函數(shù)/方法除極易簡單(簡單功能實(shí)現(xiàn),3行以內(nèi))的函數(shù)/方法外其余必須給注釋說明;每個(gè)文件頭部必須給上注釋。

1 單行注釋

【強(qiáng)制】必須獨(dú)占一行;?//?后必須跟一個(gè)空格,縮進(jìn)量整個(gè)項(xiàng)目統(tǒng)一。Ctrl+/ 快捷注釋

2 多行注釋

【強(qiáng)制】代碼中多行/方法頭注釋使用?/*...*/?格式。

3 文檔化注釋

【強(qiáng)制】為了便于代碼閱讀和自文檔化,以下內(nèi)容必須包含以/**...*/形式的塊注釋中。

以下內(nèi)容:

1、函數(shù)或方法

2、全局變量

3、文件

【強(qiáng)制】文檔注釋前必須空一行。

【建議】自文檔化的文檔說明的是what,而不是how。

4 函數(shù)/方法注釋

【強(qiáng)制】函數(shù)/方法注釋必須包含函數(shù)/方法說明,有參數(shù)和返回值時(shí)必須使用注釋標(biāo)識。備注:當(dāng)return關(guān)鍵字僅作為退出函數(shù)/方法使用時(shí),無需對返回值作注釋標(biāo)識。

示例:

/** * @Detail函數(shù)的描述* @Param p1參數(shù)1的說明* @Param p2參數(shù)2的說明,若比較長*那就換行了。* @Return返回值的描述* @Author作者* @Date日期*/functionfoo(p1:string,p2:number){? ....return{? ? p1,? ? p2? }}

【強(qiáng)制】若傳入?yún)?shù)為較為復(fù)雜的對象時(shí),必須用@param對對象中各項(xiàng)進(jìn)行標(biāo)識。

示例:

/** * @Detail函數(shù)的描述* @Param obj參數(shù)的描述文件位置* @Author作者* @Date日期*/functionfoo(obj:Object){? ...}

5 全局變量

【強(qiáng)制】全局變量必須用@global標(biāo)識。

示例:

/** * @Global user變量的描述* @Author作者* @Date日期*/letuser = {}

6 文件

【強(qiáng)制】每個(gè)文件頭部都需給上注釋,這里統(tǒng)一規(guī)定使用vscode自動(dòng)化插件生成(korofileheader)。

7 細(xì)節(jié)注釋

對于內(nèi)部實(shí)現(xiàn)、不容易理解的邏輯說明、摘要信息,我們可能需要編寫細(xì)節(jié)注釋。

【建議】細(xì)節(jié)注釋遵循單行注釋的格式。說明必須換行時(shí),每行都遵循單行注釋規(guī)范。

示例:

functionfoo(p1,p2){//這里對具體內(nèi)部邏輯進(jìn)行說明//說明太長時(shí)換到此行for(...){...}}

【建議】有時(shí)我們會(huì)使用一些特殊標(biāo)記進(jìn)行說明。特殊標(biāo)記(使用全大寫)必須使用單行注釋形式。下面列舉一些常用標(biāo)記:

1.TODO:有功能待完善。此時(shí)需要對將要實(shí)現(xiàn)的功能進(jìn)行簡單說明。

...更多見詳細(xì)版

方法命名規(guī)范

1 主要使用駝峰命名法

UserList.html --大駝峰 userList.html --首字母小寫駝峰式 userlist.html --全小寫 user-list.html --符號隔開

一般函數(shù)方法使用小駝峰命名

functiongetNumber(nTotal){}

類式組件使用大駝峰命名

classPersonInfo{constructor(name) {this.name = name;? }}

常量和私有變量使用下劃線

constMAX_COUNT =10;functiongetNumber(val){if(val <100) {? ? ? ? val =100;? ? }return_add(val);function_add(number){? ? ? ? number++;returnnumber;? ? }}

2 命名有意義

給文件命名

給方法的命名采用動(dòng)賓短語,要有邏輯意義:例如: popWindow就比 myWindow 好多了。

一般采用英文單詞全拼(除個(gè)別通用縮寫外)。

get獲取/set設(shè)置,add增加/remove刪除open打開/close關(guān)閉,edit編輯/modify修改,submit提交/commit交付find查找/search搜索clean清理/clear清除

方法定義規(guī)范

1 函數(shù)定義

使用命名函數(shù)表達(dá)式而不是函數(shù)聲明。

// badfunctionfoo(){// ...};// goodconstfoo =()=>{// ...};

不要用函數(shù)構(gòu)造器創(chuàng)建函數(shù)。

// badvaradd =newFunction('a','b','return a + b');// still badvarsubtract =Function('a','b','return a - b');

函數(shù)定義部分要有空格。

// badconstf =function(){};constg =function(){};consth =function(){};// goodconstx =function(){};consty =functiona(){};

2 不要在非函數(shù)塊內(nèi)聲明函數(shù)

不要在非函數(shù)塊(if、while?等)內(nèi)聲明函數(shù)。把這個(gè)函數(shù)分配給一個(gè)變量。這樣操作會(huì)出現(xiàn)瀏覽器優(yōu)化問題影響性能。

// badif(currentUser) {functiontest(){console.log('Nope.');? }}// goodlettest;if(currentUser) {? test =()=>{console.log('Yup.');? };}

3 關(guān)于參數(shù)

1 接收參數(shù)(強(qiáng)制)

不要用?arguments?命名參數(shù)。他的優(yōu)先級高于每個(gè)函數(shù)作用域自帶的?arguments?對象,這會(huì)導(dǎo)致函數(shù)自帶的?arguments?值被覆蓋。

// badfunctionfoo(name, options,arguments){// ...}// goodfunctionfoo(name, options, args){// ...}

不要使用?arguments,用收集參數(shù)語法?...?代替。

// badfunctionconcatenateAll(){constargs =Array.prototype.slice.call(arguments);returnargs.join('');}// goodfunctionconcatenateAll(...args){returnargs.join('');}

4 參數(shù)默認(rèn)值

用默認(rèn)參數(shù)語法而不是在函數(shù)里對參數(shù)重新賦值。

// really badfunctionhandleThings(opts){//不!我們不該修改arguments//第二:如果opts的值為false,它會(huì)被賦值為{}//雖然你想這么寫,但是這個(gè)會(huì)帶來一些微妙的bug。opts = opts || {};// ...}// still badfunctionhandleThings(opts){if(opts ===void0) {? ? opts = {};? }// ...}// goodfunctionhandleThings(opts = {}){// ...}

避免默認(rèn)參數(shù)的副作用。

varb =1;// badfunctioncount(a = b++){console.log(a);}count();// 1count();// 2count(3);// 3count();// 3

把默認(rèn)參數(shù)賦值放在最后。

// badfunctionhandleThings(opts = '123', name){// ...console.log('opts:',opts,"name",name)}//如果我不想給傳opts這個(gè)參數(shù),想使用方法定義的默認(rèn)值handleThings(undefined,'username')// opts: 123 name username// goodfunctionhandleThings(name, opts = '123'){// ...}//如果我不想給傳opts這個(gè)參數(shù),想使用方法定義的默認(rèn)值handleThings('username')// opts: 123 name username

不要對參數(shù)重新賦值。

// badfunctionf1(a){? a =1;// ...}functionf2(a){if(!a) { a =1; }// ...}// goodfunctionf3(a){constb = a ||1;// ...}functionf4(a = 1){// ...}

使用拓展運(yùn)算符調(diào)用多參數(shù)的函數(shù)。

// badconstx = [1,2,3,4,5];console.log.apply(console, x);// goodconstx = [1,2,3,4,5];console.log(...x);// badnew(Function.prototype.bind.apply(Date, [null,2016,8,5]));// goodnewDate(...[2016,8,5]);

調(diào)用或者編寫一個(gè)包含多個(gè)參數(shù)的函數(shù)的縮進(jìn),應(yīng)該像這個(gè)指南里的其他多行代碼寫法一樣——即每行只包含一個(gè)參數(shù),每行逗號結(jié)尾。

// badfunctionfoo(bar,

? ? ? ? ? ? baz,

? ? ? ? ? ? quux){// ...}// good縮進(jìn)不要太過分functionfoo(? bar,

? baz,

? quux,){// ...}// badconsole.log(foo,? bar,? baz);// goodconsole.log(? foo,? bar,? baz,);

5 箭頭函數(shù)

當(dāng)你一定要用函數(shù)表達(dá)式(在回調(diào)函數(shù)里)的時(shí)候,使用箭頭函數(shù)。

// bad[1,2,3].map(function(x){consty = x +1;returnx * y;});// good[1,2,3].map((x) =>{consty = x +1;returnx * y;});

如果函數(shù)體由一個(gè)沒有副作用的?表達(dá)式?語句組成,刪除大括號和 return。否則,使用大括號和?return?語句。

// bad[1,2,3].map((number) =>{constnextNumber =number+1;`A string containing the${nextNumber}.`;});// good[1,2,3].map((number) =>`A string containing the${number + 1}.`);// good[1,2,3].map((number) =>{constnextNumber =number+1;return`A string containing the${nextNumber}.`;});// good[1,2,3].map((number, index) =>({? [index]:number,}));//沒有明顯的return語句,可能存在副作用。functionfoo(callback){constval = callback();if(val ===true) {//當(dāng)callback返回true時(shí)...}}letbool =false;// badfoo(()=>bool =true);// good foo(()=>{ bool =true; });

如果表達(dá)式涉及多行,把他包裹在大括號或圓括號里以提高可讀性。(建議)

// bad['get','post','put'].map(httpMethod=>Object.prototype.hasOwnProperty.call(? ? httpMagicObjectWithAVeryLongName,? ? httpMethod? ));// good['get','post','put'].map(httpMethod=>{Object.prototype.hasOwnProperty.call(? ? httpMagicObjectWithAVeryLongName,? ? httpMethod? )});

在箭頭函數(shù)參數(shù)兩頭,總是使用小括號包裹住參數(shù),這樣做使代碼更清晰且一致。(建議)

// bad[1,2,3].map(x=>x * x);// good[1,2,3].map((x) =>x * x);// bad[1,2,3].map(number=>(`A long string with the${number}. It’s so long that we don’t want it to take up space on the .map line!`));// good[1,2,3].map((number) =>(`A long string with the${number}. It’s so long that we don’t want it to take up space on the .map line!`));// bad[1,2,3].map(x=>{consty = x +1;returnx * y;});// good[1,2,3].map((x) =>{consty = x +1;returnx * y;});

避免箭頭函數(shù)(=>)和比較操作符(<=,?>=)混淆. eslint:?no-confusing-arrow?(建議)

// badconstitemHeight =(item) =>item.height <=256? item.largeSize : item.smallSize;// badconstitemHeight =(item) =>item.height >=256? item.largeSize : item.smallSize;// goodconstitemHeight =(item) =>(item.height <=256? item.largeSize : item.smallSize);// goodconstitemHeight =(item) =>{const{ height, largeSize, smallSize } = item;returnheight <=256? largeSize : smallSize;};

使箭頭函數(shù)體有一個(gè)清晰的返回。 eslint:?implicit-arrow-linebreak

// bad(foo) =>? bar;(foo) =>(bar);// good(foo) => bar;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容