本文首發於個人我的網站:cherryblog.site/ (背景更換了不知道你們有沒有發現呢,嘻嘻)javascript
一個好的程序員確定是要能書寫可維護的代碼,而不是一次性的代碼,怎麼能讓團隊當中其餘人甚至一段時間時候你再看你某個時候寫的代碼也能看懂呢,這就須要規範你的代碼了。
我是有一點強迫症的人,上週咱們後端給我了一個CanUsename的接口(該接口的目的是判斷輸入的目的地是不是4級目的地),我真的是崩潰的。
我只是以爲這個名字不夠語義化,可是讓我本身想一個名字我又想不出來,因而我就在想,若是有一套命名規範的話,那麼之後起名字就不用發愁了,直接按照規範來就行了~
因而端午在家就百度了一下~css
http:
,https:
) ,除非這二者協議都不可用。不推薦:html
<script src="http://cdn.com/foundation.min.js"></script>複製代碼
推薦前端
<script src="//cdn.com/foundation.min.js"></script>複製代碼
命名方式 : 小駝峯式命名方法
命名規範 : 類型+對象描述的方式,若是沒有明確的類型,就可使前綴爲名詞vue
類型 | 小寫字母 |
---|---|
array | a |
boolean | b |
function | fn |
int | i |
object | o |
regular | r |
string | s |
推薦java
var tableTitle = "LoginTable"複製代碼
不推薦node
var getTitle = "LoginTable"複製代碼
命名方式 : 小駝峯方式 ( 構造函數使用大駝峯命名法 )
命名規則 : 前綴爲動詞jquery
動詞 | 含義 | 返回值 |
---|---|---|
can | 判斷是否可執行某個動做 ( 權限 ) | 函數返回一個布爾值。true:可執行;false:不可執行 |
has | 判斷是否含有某個值 | 函數返回一個布爾值。true:含有此值;false:不含有此值 |
is | 判斷是否爲某個值 | 函數返回一個布爾值。true:爲某個值;false:不爲某個值 |
get | 獲取某個值 | 函數返回一個非布爾值 |
set | 設置某個值 | 無返回值、返回是否設置成功或者返回鏈式對象 |
推薦:程序員
//是否可閱讀
function canRead(){
return true;
}
//獲取姓名
function getName{
return this.name
}複製代碼
命名方法 : 所有大寫
命名規範 : 使用大寫字母和下劃線來組合命名,下劃線用以分割單詞。
推薦:web
var MAX_COUNT = 10;
var URL = 'http://www.baidu.com';複製代碼
推薦(將name
換成this
是否是更熟悉了呢)
function Student(name) {
var _name = name; // 私有成員
// 公共方法
this.getName = function () {
return _name;
}
// 公共方式
this.setName = function (value) {
_name = value;
}
}
var st = new Student('tom');
st.setName('jerry');
console.log(st.getName()); // => jerry:輸出_name私有變量的值複製代碼
推薦 :
// 調用了一個函數;1)單獨在一行
setTitle();
var maxCount = 10; // 設置最大量;2)在代碼後面註釋
// setName(); // 3)註釋代碼複製代碼
*
和結束(*
/)都在一行,推薦採用單行註釋*
,最後行爲*
/,其餘行以*
開始,而且註釋文字與*
保留一個空格。/*
* 代碼執行到這裏後會調用setTitle()函數
* setTitle():設置title的值
*/
setTitle();複製代碼
函數(方法)註釋也是多行註釋的一種,可是包含了特殊的註釋要求,參照 javadoc(百度百科)
語法:
/**
* 函數說明
* @關鍵字
*/複製代碼
經常使用註釋關鍵字
註釋名 | 語法 | 含義 | 示例 |
---|---|---|---|
@param | @param 參數名 {參數類型} 描述信息 | 描述參數的信息 | @param name {String} 傳入名稱 |
@return | @return {返回類型} 描述信息 | 描述返回值的信息 | @return {Boolean} true:可執行;false:不可執行 |
@author | @author 做者信息 [附屬信息:如郵箱、日期] | 描述此函數做者的信息 | @author 張三 2015/07/21 |
@version | @version XX.XX.XX | 描述此函數的版本號 | @version 1.0.3 |
@example | @example 示例代碼 | @example setTitle('測試') | 以下 |
推薦 :
/**
- 合併Grid的行
- @param grid {Ext.Grid.Panel} 須要合併的Grid
- @param cols {Array} 須要合併列的Index(序號)數組;從0開始計數,序號也包含。
- @param isAllSome {Boolean} :是否2個tr的cols必須完成同樣才能進行合併。true:完成同樣;false(默認):不徹底同樣
- @return void
- @author polk6 2015/07/21
- @example
- _________________ _________________
- | 年齡 | 姓名 | | 年齡 | 姓名 |
- ----------------- mergeCells(grid,[0]) -----------------
- | 18 | 張三 | => | | 張三 |
- ----------------- - 18 ---------
- | 18 | 王五 | | | 王五 |
- ----------------- -----------------
*/
function mergeCells(grid, cols, isAllSome) {
// Do Something
}複製代碼
使用 HTML5 的文檔聲明類型 : <!DOCTYPE html>
說到js和css的位置,你們應該都知道js放在下面,css放在上面。
可是,若是你的項目只須要兼容ie10+或者只是在移動端訪問,那麼可使用HTML5的新屬性async
,將腳本文件放在<head>
內
兼容老舊瀏覽器(IE9-)時:
腳本引用寫在 body 結束標籤以前,並帶上 async 屬性。這雖然在老舊瀏覽器中不會異步加載腳本,但它只阻塞了 body 結束標籤以前的 DOM 解析,這就大大下降了其阻塞影響。
而在現代瀏覽器中:
腳本將在 DOM 解析器發現 body 尾部的 script 標籤才進行加載,此時加載屬於異步加載,不會阻塞 CSSOM(但其執行仍發生在 CSSOM 以後)。
綜上所述,
全部瀏覽器中推薦:
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<!-- body goes here -->
<script src="main.js" async></script>
</body>
</html>複製代碼
只兼容現代瀏覽器推薦:
<html>
<head>
<link rel="stylesheet" href="main.css">
<script src="main.js" async></script>
</head>
<body>
<!-- body goes here -->
</body>
</html>複製代碼
咱們一直都在說語義化編程,語義化編程,可是在代碼中不多有人徹底使用正確的元素。使用語義化標籤也是有理由SEO的。
語義化是指:根據元素其被創造出來時的初始意義來使用它。
意思就是用正確的標籤幹正確的事,而不是隻有div
和span
。
不推薦:
<b>My page title</b>
<div class="top-navigation">
<div class="nav-item"><a href="#home">Home</a></div>
<div class="nav-item"><a href="#news">News</a></div>
<div class="nav-item"><a href="#about">About</a></div>
</div>
<div class="news-page">
<div class="page-section news">
<div class="title">All news articles</div>
<div class="news-article">
<h2>Bad article</h2>
<div class="intro">Introduction sub-title</div>
<div class="content">This is a very bad example for HTML semantics</div>
<div class="article-side-notes">I think I'm more on the side and should not receive the main credits</div> <div class="article-foot-notes"> This article was created by David <div class="time">2014-01-01 00:00</div> </div> </div> <div class="section-footer"> Related sections: Events, Public holidays </div> </div> </div> <div class="page-footer"> Copyright 2014 </div>複製代碼
推薦
html 代碼:
<!-- The page header should go into a header element -->
<header>
<!-- As this title belongs to the page structure it's a heading and h1 should be used --> <h1>My page title</h1> </header> <!-- All navigation should go into a nav element --> <nav class="top-navigation"> <!-- A listing of elements should always go to UL (OL for ordered listings) --> <ul> <li class="nav-item"><a href="#home">Home</a></li> <li class="nav-item"><a href="#news">News</a></li> <li class="nav-item"><a href="#about">About</a></li> </ul> </nav> <!-- The main part of the page should go into a main element (also use role="main" for accessibility) --> <main class="news-page" role="main"> <!-- A section of a page should go into a section element. Divide a page into sections with semantic elements. --> <section class="page-section news"> <!-- A section header should go into a section element --> <header> <!-- As a page section belongs to the page structure heading elements should be used (in this case h2) --> <h2 class="title">All news articles</h2> </header> <!-- If a section / module can be seen as an article (news article, blog entry, products teaser, any other re-usable module / section that can occur multiple times on a page) a article element should be used --> <article class="news-article"> <!-- An article can contain a header that contains the summary / introduction information of the article --> <header> <!-- As a article title does not belong to the overall page structure there should not be any heading tag! --> <div class="article-title">Good article</div> <!-- Small can optionally be used to reduce importance --> <small class="intro">Introduction sub-title</small> </header> <!-- For the main content in a section or article there is no semantic element --> <div class="content"> <p>This is a good example for HTML semantics</p> </div> <!-- For content that is represented as side note or less important information in a given context use aside --> <aside class="article-side-notes"> <p>I think I'm more on the side and should not receive the main credits</p>
</aside>
<!-- Articles can also contain footers. If you have footnotes for an article place them into a footer element -->
<footer class="article-foot-notes">
<!-- The time element can be used to annotate a timestamp. Use the datetime attribute to specify ISO time
while the actual text in the time element can also be more human readable / relative -->
<p>This article was created by David <time datetime="2014-01-01 00:00" class="time">1 month ago</time></p>
</footer>
</article>
<!-- In a section, footnotes or similar information can also go into a footer element -->
<footer class="section-footer">
<p>Related sections: Events, Public holidays</p>
</footer>
</section>
</main>
<!-- Your page footer should go into a global footer element -->
<footer class="page-footer">
Copyright 2014
</footer>複製代碼
<img>
標籤的 alt 屬性指定了替代文本,用於在圖像沒法顯示或者用戶禁用圖像顯示時,代替圖像顯示在瀏覽器中的內容。
假設因爲下列緣由用戶沒法查看圖像,alt 屬性能夠爲圖像提供替代的信息:
從SEO角度考慮,瀏覽器的爬蟲爬不到圖片的內容,因此咱們要有文字告訴爬蟲圖片的內容
儘可能在文檔和模板中只包含結構性的 HTML;而將全部表現代碼,移入樣式表中;將全部動做行爲,移入腳本之中。
在此以外,爲使得它們之間的聯繫儘量的小,在文檔和模板中也儘可能少地引入樣式和腳本文件。
建議:
<style>.no-good {}</style>
)<hr style="border-top: 5px solid black">
)<script>alert('no good')</script>
)i.e. <b>, <u>, <center>, <font>, <b>
)i.e. red, left, center
)img
元素當作專門用來作視覺設計的元素不推薦:
<!-- We should not introduce an additional element just to solve a design problem -->
<span class="text-box">
<span class="square"></span>
See the square next to me?
</span>
css 代碼:
.text-box > .square {
display: inline-block;
width: 1rem;
height: 1rem;
background-color: red;
}複製代碼
推薦
html 代碼:
<!-- That's clean markup! --> <span class="text-box"> See the square next to me? </span> css 代碼: /* We use a :before pseudo element to solve the design problem of placing a colored square in front of the text content */ .text-box:before { content: ""; display: inline-block; width: 1rem; height: 1rem; background-color: red; }複製代碼
圖片和 SVG 圖形能被引入到 HTML 中的惟一理由是它們呈現出了與內容相關的一些信息。
不推薦
html 代碼:
<!-- Content images should never be used for design elements! -->
<span class="text-box">
<img src="square.svg" alt="Square" />
See the square next to me?
</span>複製代碼
推薦
html 代碼:
<!-- That's clean markup! --> <span class="text-box"> See the square next to me? </span> css 代碼: /* We use a :before pseudo element with a background image to solve the problem */ .text-box:before { content: ""; display: inline-block; width: 1rem; height: 1rem; background: url(square.svg) no-repeat; background-size: 100%; }複製代碼
防止全局命名空間被污染,咱們一般的作法是將代碼包裹成一個 IIFE(Immediately-Invoked Function Expression),建立獨立隔絕的定義域。也使得內存在執行完後當即釋放。
IIFE 還可確保你的代碼不會輕易被其它全局命名空間裏的代碼所修改(i.e. 第三方庫,window 引用,被覆蓋的未定義的關鍵字等等)。
不推薦:
var x = 10,
y = 100;
// Declaring variables in the global scope is resulting in global scope pollution. All variables declared like this
// will be stored in the window object. This is very unclean and needs to be avoided.
console.log(window.x + ' ' + window.y);複製代碼
推薦
// We declare a IIFE and pass parameters into the function that we will use from the global space
(function(log, w, undefined){
'use strict';
var x = 10,
y = 100;
// Will output 'true true'
log((w.x === undefined) + ' ' + (w.y === undefined));
}(window.console.log, window));複製代碼
推薦的IIFE寫法:
(function(){
'use strict';
// Code goes here
}());複製代碼
若是你想引用全局變量或者是外層 IIFE 的變量,能夠經過下列方式傳參:
(function($, w, d){
'use strict';
$(function() {
w.alert(d.querySelectorAll('div').length);
});
}(jQuery, window, document));複製代碼
ECMAScript 5 嚴格模式可在整個腳本或獨個方法內被激活。它對應不一樣的 javascript 語境會作更加嚴格的錯誤檢查。嚴格模式也確保了 javascript 代碼更加的健壯,運行的也更加快速。
嚴格模式會阻止使用在將來極可能被引入的預留關鍵字。
你應該在你的腳本中啓用嚴格模式,最好是在獨立的 IIFE 中應用它。避免在你的腳本第一行使用它而致使你的全部腳本都啓動了嚴格模式,這有可能會引起一些第三方類庫的問題。
老是使用 var 來聲明變量。如不指定 var,變量將被隱式地聲明爲全局變量,例如
var a = b = 0; //b會被隱式的建立爲全局變量複製代碼
因此,請老是使用 var 來聲明變量,而且使用單var模式(將全部的變量在函數最前面只使用一個var定義)。例如:
(function (){
'use strict'
var a = 0,
b = 0,
c = 0,
i,
j,
myObject();
}())複製代碼
採用嚴格模式帶來的好處是,當你手誤輸入錯誤的變量名時,它能夠經過報錯信息來幫助你定位錯誤出處。
javascript會自動將函數做用域內的變量和方法的定義提早(只是提早聲明,賦值仍是在原處)
例如:
(function(log){
'use strict';
var a = 10;
for(var i = 0; i < a; i++) {
var b = i * i;
log(b);
}
if(a === 10) {
var f = function() {
log(a);
};
f();
}
function x() {
log('Mr. X!');
}
x();
}(window.console.log));複製代碼
提高後的js
(function(log){
'use strict';
// All variables used in the closure will be hoisted to the top of the function
var a,
i,
b,
f;
// All functions in the closure will be hoisted to the top
function x() {
log('Mr. X!');
}
a = 10;
for(i = 0; i < a; i++) {
b = i * i;
log(b);
}
if(a === 10) {
// Function assignments will only result in hoisted variables but the function body will not be hoisted
// Only by using a real function declaration the whole function will be hoisted with its body
f = function() {
log(a);
};
f();
}
x();
}(window.console.log));複製代碼
老是使用 ===
精確的比較操做符,避免在判斷的過程當中,由 JavaScript 的強制類型轉換所形成的困擾。例如:
(function(log){
'use strict';
log('0' == 0); // true
log('' == false); // true
log('1' == true); // true
log(null == undefined); // true
var x = {
valueOf: function() {
return 'X';
}
};
log(x == 'X');
}(window.console.log));複製代碼
==等同操做符
console.log( false == null ) // false
console.log( false == undefined ) // false
console.log( false == 0 ) // true
console.log( false == '' ) // true
console.log( false == NaN ) // false
console.log( null == undefined ) // true
console.log( null == 0 ) // false
console.log( null == '' ) // false
console.log( null == NaN ) // false
console.log( undefined == 0) // false
console.log( undefined == '') // false
console.log( undefined == NaN) // false
console.log( 0 == '' ) // true
console.log( 0 == NaN ) // false複製代碼
總結一下==
==, >, <, +, -, ... 這些操做符所形成的隱式類型轉換都是無反作用的,它不會改變變量自己保存的值。,可是,若是你覆寫某個對象的
valueOf/toString
的話,==就會產生反作用.
例如:
Array.prototype.valueOf = function() {
this[0]++;
return this;
}
var x = [1, 2, 3];
x == 0;
console.log(x); // [2, 2, 3]複製代碼
===操做符:
輯操做符 || 和 && 也可被用來返回布爾值。若是操做對象爲非布爾對象,那每一個表達式將會被自左向右地作真假判斷。基於此操做,最終總有一個表達式被返回回來。這在變量賦值時,是能夠用來簡化你的代碼的。例如:若是x不存在且y不存在,x=1;若是x存在y存在,x = y
if(!x) {
if(!y) {
x = 1;
} else {
x = y;
}
}複製代碼
等同於:
x = x || y || 1;複製代碼
這一小技巧常常用來給方法設定默認的參數。
(function(log){
'use strict';
function multiply(a, b) {
a = a || 1;
b = b || 1;
log('Result ' + a * b);
}
multiply(); // Result 1
multiply(10); // Result 10
multiply(3, NaN); // Result 3
multiply(9, 5); // Result 45
}(window.console.log));複製代碼
就如eval的字面意思來講,惡魔,使用eval()函數會帶來安全隱患。
eval()函數的做用是返回任意字符串,看成js代碼來處理。
只在對象構造器、方法和在設定的閉包中使用 this 關鍵字。this 的語義在此有些誤導。它時而指向全局對象(大多數時),時而指向調用者的定義域(在 eval 中),時而指向 DOM 樹中的某一節點(當用事件處理綁定到 HTML 屬性上時),時而指向一個新建立的對象(在構造器中),還時而指向其它的一些對象(若是函數被 call() 和 apply() 執行和調用時)。
正由於它是如此容易地被搞錯,請限制它的使用場景:
函數式編程讓你能夠簡化代碼並縮減維護成本,由於它容易複用,又適當地解耦和更少的依賴。
接下來的例子中,在一組數字求和的同一問題上,比較了兩種解決方案。第一個例子是經典的程序處理,而第二個例子則是採用了函數式編程和 ECMA Script 5.1 的數組方法。
不推薦
(function(log){
'use strict';
var arr = [10, 3, 7, 9, 100, 20],
sum = 0,
i;
for(i = 0; i < arr.length; i++) {
sum += arr[i];
}
log('The sum of array ' + arr + ' is: ' + sum)
}(window.console.log));複製代碼
推薦(函數式編程):
(function(log){
'use strict';
var arr = [10, 3, 7, 9, 100, 20];
var sum = arr.reduce(function(prevValue, currentValue) {
return prevValue + currentValue;
}, 0);
log('The sum of array ' + arr + ' is: ' + sum);
}(window.console.log));複製代碼
修改內建的諸如 Object.prototype
和 Array.prototype
是被嚴厲禁止的。修改其它的內建對象好比 Function.prototype
,雖危害沒那麼大,但始終仍是會致使在開發過程當中難以 debug 的問題,應當也要避免。
用三元操做符分配或返回語句。在比較簡單的狀況下使用,避免在複雜的狀況下使用。沒人願意用 10 行三元操做符把本身的腦子繞暈。
不推薦:
if(x === 10) {
return 'valid';
} else {
return 'invalid';
}複製代碼
推薦:
return x === 10 ? 'valid' : 'invalid'複製代碼
在js規範中,有不少規範都是樣式上的規範而不是邏輯上的規範,好比儘可能使用===
而不是==
,咱們可使用JSHint或者JSLint,Javascript代碼驗證工具,這種工具能夠檢查你的代碼並提供相關的代碼改進意見。我我的使用的是JSHint,因此就以這個爲例
對於ws愛好者來講,我沒有用過其餘的編譯器,ws基本上能知足你的全部需求(最新的ws集成了vue)。
在Settings => language & frameworks => JavaScript => Code Quality Tolls => JSHint
名稱 | 含義 |
---|---|
curly | 循環或者條件語句必須使用花括號包住 |
eqeqeq | 使用強制等=== |
newcap | 對於首字母大寫的函數(聲明的類),強制使用new |
noarg | 禁用arguments.caller和arguments.callee |
sub | 對於屬性使用aaa.bbb而不是aaa['bbb'] |
undef | 查找全部未定義的變量 |
boss | 查找相似與if(a = 0)這樣的代碼 |
node | 指定運行環境爲node |
strict | 必須使用嚴格模式 |
asi | 容許省略分號 |
bitwise | 禁止使用位運算符,好比常常把&&寫錯& 規避此錯誤 |
jquery | 定義全局暴露的jQuery庫 |
evil | 禁止使用eval |
maxdepth | 嵌套的最大深度 |
maxparams | 參數的最大個數 |
ID和class的名稱老是使用能夠反應元素目的和用途的名稱,或其餘通用的名稱,代替表象和晦澀難懂的名稱
不推薦 :
.fw-800 {
font-weight: 800;
}
.red {
color: red;
}複製代碼
推薦 :
.heavy {
font-weight: 800;
}
.important {
color: red;
}複製代碼
通常狀況下ID不該該被用於樣式,而且ID的權重很高,因此不使用ID解決樣式的問題,而是使用class
不推薦:
#content .title {
font-size: 2em;
}複製代碼
推薦:
.content .title {
font-size: 2em;
}複製代碼
從結構、表現、行爲分離的原則來看,應該儘可能避免css中出現HTML標籤,而且在css選擇器中出現標籤名會存在潛在的問題。
不少前端開發人員寫選擇器鏈的時候不使用 直接子選擇器(注:直接子選擇器和後代選擇器的區別)。
有時,這可能會致使疼痛的設計問題而且有時候可能會很耗性能。
然而,在任何狀況下,這是一個很是很差的作法。
若是你不寫很通用的,須要匹配到DOM末端的選擇器, 你應該老是考慮直接子選擇器。
不推薦:
.content .title {
font-size: 2rem;
}複製代碼
推薦
.content > .title {
font-size: 2rem;
}複製代碼
儘可能使用縮寫屬性對於代碼效率和可讀性是頗有用的,好比font屬性。
不推薦:
border-top-style: none;
font-family: palatino, georgia, serif;
font-size: 100%;
line-height: 1.6;
padding-bottom: 2em;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;複製代碼
推薦:
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;複製代碼
省略0後面的單位,
不推薦:
padding-bottom: 0px;
margin: 0em;複製代碼
推薦:
padding-bottom: 0;
margin: 0;複製代碼
做爲最佳實踐,咱們應該遵循如下順序(應該按照下表的順序):
結構性屬性:
表現性屬性:
不推薦:
.box {
font-family: 'Arial', sans-serif;
border: 3px solid #ddd;
left: 30%;
position: absolute;
text-transform: uppercase;
background-color: #eee;
right: 30%;
isplay: block;
font-size: 1.5rem;
overflow: hidden;
padding: 1em;
margin: 1em;
}複製代碼
推薦:
.box {
display: block;
position: absolute;
left: 30%;
right: 30%;
overflow: hidden;
margin: 1em;
padding: 1em;
background-color: #eee;
border: 3px solid #ddd;
font-family: 'Arial', sans-serif;
font-size: 1.5rem;
text-transform: uppercase;
}複製代碼
相關文章: