JavaScript 編碼規範(Google Coding-style for JavaScript)

Google JS 規範

背景:

JavaScript作爲一門弱類型腳本語言,其代碼規範一直飽受質疑。它不像java有嚴格的語法規範。大家都有一套自己的JS代碼規範,所以JS代碼的維護及二次開發也一直是讓人頭痛。故規範大家的JS代碼,形成統一的規範是很有必要的。這裏所羅列的規範並不是官方指南,而是大家的一種共識。本文是翻譯的google的coding style

鏈接:http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml

下面從兩個方面來介紹js的語法規範

一. js語法規範

1. 聲明變量 必須使用var來聲明變量。

 var time = 20;
2. 常量 使用大寫字母,每個單詞之間使用下劃線分割:

 var LIMIT_PAGE_NUMBER = 20;
3. 必須以分號作爲語句的結束。在js中,如果不添加分號,使用回車符,也能被瀏覽器識別,但是爲了語法的規範,必須使用分號作爲結束符。

 if(1) {time = 2;}
4. 在必要的時候,使用匿名函數。
5. 在代碼塊中,聲明函數須有變量接收

// Not recommended
if (x) {
  function foo() {}
}
// Recommended
if (x) {
  var foo = function() {};
}

6. 異常 異常在你的工作中基本上都會遇到,如果你正在做大型的項目(比如使用框架等),就大膽地使用異常處理
7. 不要將基本類型再包裝成object

// Not recommended
var x = new Boolean(false);
if (x) {
  alert('hi');  // Shows 'hi'.
}
// Recommended
var x = Boolean(0);
if (x) {
  alert('hi');  // This will never be alerted.
}
typeof Boolean(0) == 'boolean';
typeof new Boolean(0) == 'object';
8. 對象的層次結構不要太深
9. 刪除
// Not recommended
Foo.prototype.dispose = function() {
  delete this.property_;
};
// Recommended
Foo.prototype.dispose = function() {
  this.property_ = null;
};
10. 方法的提取 將不相關的提取在一起。
// Not recommended
function foo(element, a, b) {
  element.onclick = function() { /* uses a and b */ };
}
// Recommended
function foo(element, a, b) {
  element.onclick = bar(a, b);
}
function bar(a, b) {
  return function() { /* uses a and b */ };
}
11. 儘量少使用eval函數
12. 儘量少使用with函數
13. this關鍵字的使用 只允許在構造函數,方法中使用
14. for-in循環容易出錯,只允許迭代key在object/map/hash中的
以下的寫法經常容易出錯:
function printArray(arr) {
  for (var key in arr) {
    print(arr[key]);
  }
}

printArray([0,1,2,3]);  // This works.

var a = new Array(10);
printArray(a);  // This is wrong.

a = document.getElementsByTagName('*');
printArray(a);  // This is wrong.

a = [0,1,2,3];
a.buhu = 'wine';
printArray(a);  // This is wrong again.
a = new Array;
a[3] = 3;
printArray(a);  // This is wrong again.
//改良版本
function printArray(arr) {
  var l = arr.length;
  for (var i = 0; i < l; i++) {
    print(arr[i]);
  }
}
15. 不允許將array用作map/hash/associative array
16. 多個字符串字面量
// Not recommended
var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';


// Recommended
var myString = 'A rather long string of English text, an error message ' +
    'actually that just keeps going and going -- an error ' +
    'message to make the Energizer bunny blush (right through ' +
    'those Schwarzenegger shades)! Where was I? Oh yes, ' +
    'you\'ve got an error and all the extraneous whitespace is ' +
    'just gravy.  Have a nice day.';

17. array和object字面量

// Not recommended
	// Length is 3.
var a1 = new Array(x1, x2, x3);

// Length is 2.
var a2 = new Array(x1, x2);

// If x1 is a number and it is a natural number the length will be x1.
// If x1 is a number but not a natural number this will throw an exception.
// Otherwise the array will have one element with x1 as its value.
var a3 = new Array(x1);

// Length is 0.
var a4 = new Array();


// Recommended
var a = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];


再比如:

// Not recommended
var o = new Object();
var o2 = new Object();
o2.a = 0;
o2.b = 1;
o2.c = 2;
o2['strange key'] = 3;

// Recommended
var o = {};
var o2 = {
  a: 0,
  b: 1,
  c: 2,
  'strange key': 3
};

18. 不允許修改js內置對象的prototype屬性

二.js風格規範

1. 命名

functionNamesLikeThis;
variableNamesLikeThis;
ClassNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
CONSTANT_VALUES_LIKE_THIS;
foo.namespaceNamesLikeThis.bar;
filenameslikethis.js;
2. 自己實現toString方法(和java類似)
3. 延遲初始化。
//not recommended
	var time = 23;
//recommended	
	var time;
	//toDo other action... ...
	time = 23;
4. 明確作用範圍,在作用域鏈中,不要依賴於windows這個對象,有可能在另個應用中windows就不是指這個內容窗口了。
5. 代碼格式化:
記得使用大括號
if (something) {
  // ...
} else {
  // ...
}
       array和object的初始化:
var arr = [1, 2, 3];  // No space after [ or before ].
		var obj = {a: 1, b: 2, c: 3};  // No space after { or before }.
		// Object initializer.
		var inset = {
		  top: 10,
		  right: 20,
		  bottom: 15,
		  left: 12
		};
數組格式化

this.rows_ = [
		  '"Slartibartfast" <[email protected]>',
		  '"Zaphod Beeblebrox" <[email protected]>',
		  '"Ford Prefect" <[email protected]>',
		  '"Arthur Dent" <[email protected]>',
		  '"Marvin the Paranoid Android" <[email protected]>',
		  '[email protected]'
		];
		// Four-space, wrap at 80.  Works with very long function names, survives
		// renaming without reindenting, low on space.
		goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
		    veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
		    tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
		  // ...
		};
		
		// Four-space, one argument per line.  Works with long function names,
		// survives renaming, and emphasizes each argument.
		goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
		    veryDescriptiveArgumentNumberOne,
		    veryDescriptiveArgumentTwo,
		    tableModelEventHandlerProxy,
		    artichokeDescriptorAdapterIterator) {
		  // ...
		};
		
		// Parenthesis-aligned indentation, wrap at 80.  Visually groups arguments,
		// low on space.
		function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
		             tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
		  // ...
		}
		
		// Parenthesis-aligned, one argument per line.  Emphasizes each
		// individual argument.
		function bar(veryDescriptiveArgumentNumberOne,
		             veryDescriptiveArgumentTwo,
		             tableModelEventHandlerProxy,
		             artichokeDescriptorAdapterIterator) {
		  // ...
		}
如果方法參數很長,並伴隨有運算符時:
if (veryLongFunctionNameA(
		        veryLongArgumentName) ||
		    veryLongFunctionNameB(
		    veryLongArgumentName)) {
		  veryLongFunctionNameC(veryLongFunctionNameD(
		      veryLongFunctioNameE(
		          veryLongFunctionNameF)));
		}
6. 字符串的聲明時,使用單引號
var msg = 'This is some HTML';
7. 添加private和protected方法註釋
/** @constructor */
		AA_PublicClass = function() {
		  /** @private */
		  this.privateProp_ = 2;
		
		  /** @protected */
		  this.protectedProp = 4;
		};
		
		/** @private */
		AA_PublicClass.staticPrivateProp_ = 1;
		
		/** @protected */
		AA_PublicClass.staticProtectedProp = 31;
		
		/** @private */
		AA_PublicClass.prototype.privateMethod_ = function() {};
		
		/** @protected */
		AA_PublicClass.prototype.protectedMethod = function() {};
8. JS 類型
基本類型     null,underfine, boolean, number,string  
9. 註釋 
js支持單行註釋,和文檔註釋。
//Test demo 單行註釋
		/** @constructor */
		project.MyClass = function() {
		  /**文檔註釋
		   * Maximum number of things per pane.
		   * @type {number}
		   */
		  this.someProperty = 4;
		}
10. JS Tips and Tricks
  1. True and false boolean 表達式
接下來的都是false 
null
undefined
'' the empty string
0 the number
但是接下來的又都是true
'0' the string
[] the empty array
{} the empty object
所以對於以下的寫法
not recommended
//not recommended
while (x != null) {}
//recommended
while (x) {}
//not recommended
if (y != null && y != '') {}
//recommended
if (y) {}
請記得以下的boolean:
Boolean('0') == true
'0' != true
0 != null
0 == []
0 == false
Boolean(null) == false
null != true
null != false
Boolean(undefined) == false
undefined != true
undefined != false
Boolean([]) == true
[] != true
[] == false
Boolean({}) == true
{} != true
{} != false
2. 對於&&和||
/** @param {*=} opt_win */
function foo(opt_win) {
  var win;
  if (opt_win) {
    win = opt_win;
  } else {
    win = window;
  }
  // ...
}
you can write this:

/** @param {*=} opt_win */
function foo(opt_win) {
  var win = opt_win || window;
  // ...
}

if (node) {
  if (node.kids) {
    if (node.kids[index]) {
      foo(node.kids[index]);
    }
  }
}
you could do this:

if (node && node.kids && node.kids[index]) {
  foo(node.kids[index]);
}
or this:

var kid = node && node.kids && node.kids[index];
if (kid) {
  foo(kid);
}
3. 對於迭代
//not recommended
var paragraphs = document.getElementsByTagName('p');
for (var i = 0; i < paragraphs.length; i++) {
  doSomething(paragraphs[i]);
}
//It is better to do this instead:
//recommended
var paragraphs = document.getElementsByTagName('p');
for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
  doSomething(paragraph);
}
發佈了29 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章