Also available on Github JSHint配置詳解
增強參數(Enforcing Options)
本類參數設為true,JSHint會產生更多告警。
-
bitwise
禁用位運算符(如^,|,&)
位運算符在JS中很少使用,性能也較差,出現&也很可能是想寫&&。
-
camelcase
使用駝峰命名(camelCase)或全大寫下划線命名(UPPER_CASE)
這是條最佳實踐,關鍵不在於采用什么樣的命名規則(比如純小寫配下划線),而在於要有規則,在代碼中看到不同的命名規則會讓人頭痛不已。
-
curly
if和while等語句中使用{}來明確代碼塊
while (day)
shuffle();
sleep();雖然縮進表示兩條語句都在循環中,但事實卻是只有一句循環。
-
eqeqeq
使用=和!替代==和!=
==和!=比較時會對前后元素進行自動轉義,作為讀者,需要動腦筋想這里可能有什么樣的轉義規則,加重負擔;作為作者,其實很可能是不確定這段代碼運行時是怎么樣的,想要偷懶。
-
es3
強制使用ECMAScript 3規范
-
forin
在for in循環中使用Object.prototype.hasOwnProperty()來過濾原型鏈中的屬性
for (key in obj) {
if (obj.hasOwnProperty(key)) {
// We are sure that obj[key] belongs to the object and was not inherieted.
}
}for in遍歷對象屬性的時候,包括繼承自原型鏈的屬性,hasOwnProperty可以來判斷一個屬性是否是對象本身的屬性而不是繼承得來的。
-
freeze
禁止復寫原生對象(如Array, Date)的原型
/* jshint freeze:true */
Array.prototype.count = function (value) { return 4; };
// -> Warning: Extending prototype of native object: 'Array'.為原生對象添加屬性確實看上去很方便,但也帶來了潛在的問題,一是如果項目中有多處為同一個對象添加了同樣的屬性(或函數),則很可能產生沖突;二是如果某段邏輯依賴於對象屬性遍歷,則可能產生錯誤。
-
immed
匿名函數調用必須
(function() {
// body
}());而不是
(function() {
// body
})();這是為了表明,表達式的值是函數的結果,而不是函數本身。
-
indent
代碼縮進寬度(空格數)
前面幾個項目我比較喜歡4,新項目我又在嘗試2。關鍵不在於是幾,而在於大家都要設成一樣的。
-
latedef
變量定義前禁止使用
JS的變量是“函數級作用域”,而不是通常所見的“塊級作用域”,簡單說
function sum(numbers) {
for (var i = 0, n = numbers.length; i < n; i++) {
var sum = sum + numbers[i];
}return sum;
}
相當於
function sum(numbers) {
var i, n, sum;for (i = 0, n = numbers.length; i < n; i++) { sum = sum + numbers[i]; } return sum;
}
這個行為叫做“變量聲明提升”,為了不產生混淆,這條規則建議函數都使用第二種寫法。
-
newcap
構造函數名首字母必須大寫
這條最佳實踐是為了方便區分構造函數和普通函數,這樣在直接調用大寫字母開頭的函數時,使用者就會想想是不是自己寫錯了。
不通過new而直接調用構造函數,會使得構造函數中的this指向global對象,從而產生錯誤。
PS. 有些高手可以通過在構造函數中判斷this的指向來判斷是否重新new自身,從而讓構造函數也能直接調用產生新對象。但這有些高深,加重開發人員和使用人員的負擔,也不利於統一編碼風格。
-
noarg
禁止使用arguments.caller和arguments.callee
一方面這兩個屬性不是所有的瀏覽器都支持,另一方面這兩個屬性的使用會導致JS引擎很難優化代碼,在未來的JS規范中會被去掉,所以不建議使用。
-
noempty
禁止出現空的代碼塊
空的代碼塊並不是有害的,但是出現的話我們需要考慮下為什么。
-
nonbsp
禁止"non-breaking whitespace"
這是Mac鍵盤在某種情況下可以鍵入的字符,據說會破壞非UTF8編碼的頁面。
-
nonew
禁止使用構造器
new MyConstructor();
構造一個對象,卻不給它賦值到某個變量,只是利用構造函數中的邏輯。這個行為完全可以用一個普通函數來完成,不應該借助構造器。
-
plusplus
禁止使用++和--
不是很贊成把這個選項打成true,不過亂用自增/自減確實也會帶來閱讀上的障礙。
-
quotemark
統一使用單引號或雙引號
這個最佳實踐要求代碼風格統一,我比較喜歡統一成單引號。
這是為什么規定最佳實踐的一個好例子,在寫到字符串的時候我們就不用考慮使用單引號好還是用雙引號好,就都用單引號,這在一定程度上也減輕了我們的思考負擔。
-
undef
禁止使用不在全局變量列表中的未定義的變量
function test() {
var myVar = 'Hello, World';
console.log(myvar); // Oops, typoed here. JSHint with undef will complain
}如果本地作用域里的變量沒有使用var來聲明,則會被放到全局作用域下面,眾所周知,全局變量時罪惡的源泉。
-
unused
禁止定義變量卻不使用
function test(a, b) {
var c, d = 2;
return a + d;
}
test(1, 2);
// Line 1: 'b' was defined but never used.
// Line 2: 'c' was defined but never used.這種變量通常是寫作過程中遺留下來的垃圾,需要及時清理掉。
-
strict
強制使用ES5的嚴格模式
Strict Mode是對JS用法的一些限制,過濾掉了容易出錯的特性和不容易優化的特性。
通過在函數開頭處加入'use strict';來觸發嚴格模式,不要在文件頭部加入,因為在JS鏈接的時候很可能就失效了。
-
trailing
禁止行尾空格
-
maxparams
函數可以接受的最大參數數量
函數參數數量應該控制在3個以內,超出則可能造成使用困難,比如需要記憶參數順序,難以設定默認值等。另外,在JS中可以很方便的使用參數對象來封裝多個參數。
-
maxdepth
代碼塊中可以嵌入{}的最大深度
-
maxstatement
函數中最大語句數
-
maxcomplexity
函數的最大圈復雜度
-
maxlen
一行中最大字符數
這個是為了減輕代碼閱讀的困難,簡單說就是不要折行。
上面四個參數最終都是為了減小代碼的復雜程度,簡單輕巧的代碼片段更容易閱讀和維護。
松弛參數(Relaxing Options)
本類參數設為true,JSHint會產生更少告警。
-
asi
允許省略分號
JavaScript的語法允許自動補全分號,但是這一特性也會造成難以定位的錯誤,所以建議寫代碼時不要省略分號。
-
boss
允許在if,for,while語句中使用賦值
在條件語句中使用賦值經常是筆誤if (a = 10) {},但是牛人(boss)可以把這個特性用的很好,我們作為普通人就算了。
-
debug
允許debugger語句
debugger語句在產品代碼中應該去掉。
-
eqnull
允許==null
null通常用來比較= null || === undefined
-
esnext
允許ECMAScript 6規約
目前ES6的特性不是所有的瀏覽器都支持。
-
evil
允許使用eval
eval有“注入攻擊”的危險,另一方面也不利於JS引擎優化代碼,所以盡量不要使用。
-
expr
允許應該出現賦值或函數調用的地方使用表達式
-
funcscope
允許在控制體內定義變量而在外部使用
function test() {
if (true) {
var x = 0;
}x += 1; // Default: 'x' used out of scope. // No warning when funcscope:true
}
雖然“變量聲明提升”使得上面的代碼可以運行通過,但是讀者還是會感到頭暈。
-
globalstrict
允許全局嚴格模式
在strict中解釋了,'use strict';放在全局域可能造成JS文件鏈接錯誤。
-
iterator
允許__iterator__
不是所有的瀏覽器都支持__iterator__。
-
lastsemic
允許單行控制塊省略分號
var name = (function() { return 'Anton' }());
高手用得到的特性,我們還是堅持加上分號吧。
-
laxbreak
允許不安全的行中斷(與laxcomma配合使用)
-
laxcomma
允許逗號開頭的編碼樣式
var obj = {
name: 'Anton'
, handle: 'valueof'
, role: 'SW Engineer'
}; -
loopfunc
允許循環中定義函數
在循環中定義函數經常會導致錯誤:
var nums = [];
for (var i = 0; i < 10; i++) {
nums[i] = function (j) {
return i + j;
};
}nums0; // Prints 12 instead of 2
錯誤的根源在於function(j)中的i是對循環中的i的引用,而不是賦值。所以在最終函數執行時,i的值是10。
修改的方法是使用閉包:
var nums = [];
for (var i = 0; i < 10; i++) {
(function (i) {
nums[i] = function (j) {
return i + j;
};
}(i));
} -
maxerr
JSHint中斷掃描前允許的最大錯誤數
因為最終我們需要清零JSHint報錯的,所以這個值用在對已有項目的掃描中。
-
multistr
允許多行字符串
-
notypeof
允許非法的typeof操作
-
proto
允許 proto
不是所有的瀏覽器都支持__proto__.
-
smarttabs
允許混合tab和space排版
SmartTabs方法使用tab進行縮進,使用空格進行代碼對齊。比較高級的用法,有興趣的話可以嘗試下。
-
shadow
允許變量shadow
function test() {
var x = 10;if (true) { var x = 20; } return x;
}
基於“函數作用域”,多次定義變量和單次定義是沒有區別的,但是會造成閱讀障礙。
-
sub
允許person['name']
JSHint推薦使用person.name代替person['name']
-
supernew
允許new function() {...}和new Object;
-
validthis
允許嚴格模式下在非構造函數中使用this
-
noyield
允許發生器中沒有yield語句
環境參數(Enviroments)
預定義一些全局變量,如node等,沒什么好理解的。