web前端

命名規範

文件和文件夾命名

命名規範

文件和文件夾命名

文件夾和文件名採用英文小寫字母命名,多個英語單詞用 “-” 分割,不使用駝峯命名,如:hello-world

編寫組件使用 “c-” 打頭,如:編寫一個select組件,文件夾或者文件名定義[c-select]

樣式表命名

樣式表命名採用英文小寫字母命名,多個英語單詞用 “-” 分割,不使用駝峯命名,如:hello-world

JS命名

js變量使用駝峯命名,不使用-號分割

// 不推薦let foo_bar = 'hello eleme';// 推薦let fooBar = 'hello eleme';

常量要大寫

// 不推薦let prefix = 'https://www.javanx.cn/';let Prefix = 'http://www.javanx.cn/'// 推薦const PREFIX = 'www.javanx.cn';

定義dispatch或者commit的請求類型時,按照A_打頭代表action,M_打頭代表mutation的方式區分請求類型

註釋命名

在stylus和js文件中添加註釋時,在“//”後面加入空格再添加文字

/*不推薦*///不推薦; // 不推薦/* 推薦 */// 推薦;

在寫pug模板時,在“//”後面最好加上-再空格,因爲“//”會被轉義成,“//-”不會被轉義成任何東西

統一代碼風格

Stylus代碼風格

2個空格縮進,UTF-8 編碼

如果你的代碼中包含大括號,確保大括號與選擇器之間留空,冒號後面留空,註釋內外前後留空

/* 我是註釋 */div { /* 我是註釋 */ }span { color: red; /* 我是註釋 */}

一個選擇器中有多個樣式聲明時每條寫一行

多個選擇器使用逗號隔開時寫在不同的行,修改時不容易漏掉逗號後面的選擇器

div,span color: red font-size: 12px

用逗號分隔的多個樣式值寫成多行,便於閱讀與編輯

.block box-shadow: 0 0 0 rgba(#000, 0.1), 1px 1px 0 rgba(#000, 0.2), 2px 2px 0 rgba(#000, 0.3), 3px 3px 0 rgba(#000, 0.4), 4px 4px 0 rgba(#000, 0.5)

避免使用 ID 選擇器,權重太高,不易維護

@require和@import支持引入css文件,避免首頁產生過多HTTP請求,可以使用這兩個關鍵字合併css文件

0 值的單位建議省略,但不強制,因爲大部分 0 值的單位是沒用的

類名中的字母一律小寫,只使用字母、數字以及“-”,因爲解析樣式表時不區分大小寫

JS代碼風格

2個空格縮進,UTF-8 編碼

打開嚴格模式

'use strict'; // 寫在文件頂端

使用單引號,這樣可以跟 HTML 的雙引號更好的一起工作

在語句(Statement)的結尾加分號

// 不建議const fn = function() { // Long code} // 沒有分號// 建議const fn = function() { // Long code}; // 這裏有分號/* 踩坑 */const f1 = function ff1() { return function() { return 1; };} // 此處漏寫分號(function() { // 此處調用了上面的ff1,WHAT THE FUCK})();console.log(f1); // 1const f2 = function ff2() { return function() { return 1; };} // 此處漏寫分號// IIFE;(function() { // 注意前面的分號})();console.log(f2); // function

在二元和三元運算符的符號與操作數之間添加空格,在非行末的 , ; } 後添加空格,在 { 前添加空格。並在每個邏輯塊中間添加空白行。 特別的,在 if、while 等關鍵字後加空格,與函數調用做區分

// 不推薦let foo='bar',hello=foo+2,test=true;function hi(){ // ...}if(foo&&hello){ // ...}else if(foo){ // ...}else if(! test){ // ...}// 推薦let foo = 'bar';let hello = foo + 2;let test = true;function hi(arg1, arg2) { // ...}if (foo && hello) { // ...} else if (foo) { // ...} else if (!test) { // ...}

不要爲大括號另寫一行

// 不推薦if (foo){ // ...}// 推薦if (foo) { // ...}// 不允許return{ a: 1};// 一定要return { a: 1};

寫 else 時不要另起一行

// 不推薦if (test) { things1(); things2();}else { things3();}// 推薦if (test) { things1(); things2();} else { things3();}

使用變量之前必須先定義,不要定義全局變量

// 變量 undefinedVar 從未定義過undefinedVar = 1; // 嚴格模式中報錯console.log(global.undefinedVar); // 1// 不推薦let hello = 1, world = 2;// 推薦let hello = 1;let world = 2;let foo, fee, fxx;/* 變量和閉包遇到的坑 */void function () { for (let i = 0; i < arr.length; ++i) { (function () { console.log(i); // undefined i不在閉包範圍內 for (let i = 0; i < 10; ++i) { // Do some other things } })(); }}();const elements = [ div1, div2, div3 ];for (let i = 0; i < elements.length; ++i) { elements[i].addEventListener('event', function() { console.log(i); // 3 });}

使用字面量

// 不建議const obj = new Object();const array = new Array();// 推薦const obj = {};const array = [];// 鑑於 Array 構造函數的特殊性,不建議const arr1 = new Array(4, 5, 6); // [4, 5, 6]// 以免與下面混淆const arr2 = new Array(4); // [ undefined * 4 ]// 等價於(不推薦)const arr3 = [];arr3.length = 4;// 等價於(不推薦)const arr4 = [,,,,];console.log('0' in arr2, '0' in arr3, '0' in arr4); // false, false, false// 不推薦let str = new String('str');console.log(str === 'str'); // falselet bool = new Boolean(false);if (bool) { console.log('wat'); // wat}// 當真需要使用字面量包裝類時,使用顯式強制轉換(請先三思)let strObject = Object('str');strObject.customProperty = someValue;

建議使用 ===/!== 而非 ==/!=,== 的規則比較複雜,大家可能記不住

// 不推薦function foo(a) { if (a == 123) { // ... }}// 推薦function foo(a) { a = Number(a); if (a === 123) { // ... }}// 隱式轉換let a = '';// falseif (a === 0);// trueif (a == 0);

對於可能不存在的全局引用可以先做如此判斷

if (typeof localStorage !== 'undefined') {

// 此時訪問 localStorage 絕對不會出現引用錯誤

}

// Or

if ('localStorage' in self) {

// 此時訪問 localStorage 絕對不會出現引用錯誤

}

/* 區分 undefined */

let a = undefined;

// 判斷一個全局變量是否有聲明

'a' in self; // true

// 判斷一個變量是否爲 undefined 並將未聲明的引用作爲 undefined 處理

typeof a !== 'undefined'; // false

避免無必要的 if 語句、三元運算符

const arr = [1, 2, 3];// 不推薦let flag1 = arr.length > 0 ? true : false;// 不推薦let flag2;if (arr.length > 0) { flag2 = true;} else { flag2 = false;}// 推薦let flag3 = arr.length > 0;

合理的格式化三元運算符

// 不推薦let flag1 = veryLooooooooooonnnnggggggCondition ? resultWhenTruth : resultWhenFalsy;// 推薦let flag2 = veryLooooooooooonnnnggggggCondition ? resultWhenTruth : resultWhenFalsy;

複雜邏輯中建議使用顯式轉換

+num === Number(num);!!bool === Boolean(bool);str + '' === String(str);// 特別的if (bool)// 等價於if (Boolean(bool))// 故if ([]) { console.log('true'); // true}// 而if ([] === true) { console.log('true'); // 無輸出}// 另外if (Boolean(String(false))) { console.log('true'); // true}

不要使用 parseInt 做整數轉換,如需使用 parseInt,請給它傳入第二個參數 10,在IE上有BUG,WHAT THE FUCK

let floatValue = 123.456;// 不要let intValue = parseInt(floatValue);// 可以用let intValue2 = floatValue | 0;// 更顯然的let intValue3 = Math.floor(floatValue);

特殊的數字處理使用 parseFloat 作轉換

// 例如有://

let divWidth = getComputedStyle(document.getElementById('div')).width; // '10px'console.log(parseFloat(divWidth)); // 10console.log(Number(divWidth)); // NaNconsole.log(+divWidth); // NaN

如果想自定義的函數按照從上至下的順序被執行,那你需要使用表達式來定義函數,而不是函數語句

// 不推薦function fee() { // ...}// 推薦const foo = function() { // ...};/* confused */void function() { // 此處可以正常使用函數,但邏輯不清晰 foo(); return null; function foo() {};}();

只引用一次的函數建議匿名定義,因爲名稱存在主觀因素

// 不推薦const foo = function() { // ...};element. = foo;// 推薦element. = function() { // ...};

自執行函數

// 不推薦(function() { // ...})();+function() { // ...}();// 推薦!function() { // ...}();// 推薦void function() { // ...}();/* 踩坑 */let a = 1 // 此處無分號+function() { return 2}();// 此處 a 的值爲 3

使用Promise解決嵌套問題

// 不推薦async1(function() { // TODO 1 async2(function() { // TODO 2 async3(function() { // TODO 3 }); });});// 推薦Promise.resolve() .then(function() { return new Promise(function(resolve) { async1(resolve); }); }) .then(function() { // TODO 1 return new Promise(function(resolve) { async2(resolve); }); }) .then(function() { // TODO 2 return new Promise(function(resolve) { async3(resolve); }); }) .then(function() { // TODO 3 });

禁止使用未定義的變量

禁止使用 eval,非用不可時可以使用 Function 構造器替代

禁止使用 with 語句

禁止在塊作用域中使用函數聲明語句

if (true) { // 禁止 function func1() { // ... } // 允許 const func2 = function() { // ... };}

禁止使用 arguments 映射

void function(a) { arguments[0]++; // 此處 a 爲 2}(1);

禁止使用保留字做變量名如 interface 等

還有哪些問題歡迎補充,一起討論哈。

查看原文 >>
相關文章