JSHint 是用来检测javascript代码的一款开源工具,他可以发现代码错误、查找代码潜在的问题。通过定制JSHint配置文件,可以使团队按照俗称的规范来开发项目。
JSHint is a community-driven tool to detect errors and potential problems in JavaScript code and to enforce your team's coding conventions. It is very flexible so you can easily adjust it to your particular coding guidelines and the environment you expect your code to execute in. JSHint is open source and will always stay this way.
我们可以直接从官网下载jshint.js。对于nodejs项目,可以执行以下命令 npm install jshint -g 来安装。 当然对于ide,jshint提供了相应的插件,例如:eclipse、netbeans、webstorm、nodepad++等。下面的介绍是基于2.3.0版本,官方正在计划推出3.0版本。
下载最新版的jshint.js后引入到要测试的html文件中。jshint 提供了一个全局函数 JSHINT(source, options, globals) 用来检测javascript代码,该方法中有三个参数。
第一个参数可以是一个字符串或者是一个字符串数组。如果是字符串,则他会被\n和\r分割,如果传入的参数是数组,就要保证数组的每一项是一行代码。 因此源码参数可以是javascript代码或者是一个json形式。
第二个参数 options 是一个可选配置项。options是一个json格式的object,大部分属性是 boolean 类型的,当设置为true,如果代码没有通过检验会显示错误警告的。
第三个参数 globals是指定全局变量。
调用方法 JSHINT(source, options, globals) 后,如果所有的验证都通过,JSHint会返回true,否则返回false。当返回false的时候,可以用 JSHint.errors 来获取错误信息或者用JSHint.data()来获取lint信息。
我们也可以在测试代码中定义配置项,例如:
/*jshint evil:true, boss:true */
而设定global参数可以告诉JSHint,全局的变量配置。 例如
/*global DISQUS: true, jQuery: false */
以上的这个例子是告诉JSHint,DISQUS是你自己声明的全局变量,而jQuery是你引入的全局变量
jsHint中几个主要的方法和属性
上面已介绍过,用来检查代码的全局函数
返回是一个对象组成的数组,格式如下
{ id: id号, scope: 上下文, line: 错误的行数, charater: 错误的字符数, reason: 问题详细描述信息, evidence: 出错的代码, raw: 原本的错误描述信息, code: 出错代码类型, a: the first detail, b: the second detail, c: the third detail, d: the fourth detail } function main() { eval('console.info(2);'); return 'Hello, World!'; } main(); //检测上面代码会返回以下错误信息 { id: '(error)', scope: '(main)', line: 2, charater: 3, reason: 'eval can be harmful.', evidence: ' eval('console.info(2);');', raw: 'eval can be harmful.', code: 'W061', a: undefined, b: undefined, c: undefined, d: undefined }
返回一个object格式的数据结果
JSHint中好像没有专门处理国际化的配置,如果想国际化,我们只能修改源代码了,找到相应的errors、warnings和info变量,修改其为中文即可,关于翻译,可以参考这篇文章。以下是部分翻译,待整理
globalMsg = { "Missing semicolon." : "缺少分号.", "Use the function form of \"use strict\"." : "使用标准化定义function.", "Unexpected space after ‘-’." : "在’-'后面不应出现空格.", "Expected a JSON value." : "请传入一个json的值.", "Mixed spaces and tabs.": "空格和TAB重复.", "Unsafe character." : "不安全的字符.", "Line too long.": "本行中的字符超过设定的最大长度.", "Trailing whitespace.": "本行末尾有过多无用空格.", "Script URL." : "脚本URL.", "Unexpected {a} in ‘{b}’." : "在 ‘{b}’ 中不该出现 {a}.", "Unexpected ‘{a}’." : "不该在此出现’{a}’.", "Strings must use doublequote." : "字符串需要用双引号", "Unnecessary escapement." : "不需要转义", "Control character in string: {a}." : "在字符串中出现了Control的字符", "Avoid \\’." : "避免 \\", "Avoid \\v." : "避免 \\v", "Avoid \\x-." : "避免 \\x-", "Bad escapement." : "错误的转义字符", "Bad number ‘{a}’." : "错误的数字 ‘{a}’", "Missing space after ‘{a}’." : "在’{a}’之后缺少空格", "Don’t use extra leading zeros ‘{a}’." : "不要再’{a}’的前面用多余的0″, "Avoid 0x-. ‘{a}’." : "避免使用 0x-. ‘{a}’.", "A trailing decimal point can be confused with a dot ‘{a}’." : "在’{a}’中使用点尾随小数点", "Unexpected comment." : "不该在此处出现注释", "Unescaped ‘{a}’." : "没有转义 ‘{a}’", "Unexpected control character in regular expression." : "在正则表达式中出现了control字符", "Unexpected escaped character ‘{a}’ in regular expression." : "在正则表达式中出现了没有转义的字符 ‘{a}’", "Expected ‘{a}’ and instead saw ‘{b}’." : "应该用 ‘{a}’代替’{b}’", "Spaces are hard to count. Use {{a}}." : "空格难以统计,请使用 {{a}}", "Insecure ‘{a}’." : "不安全的 ‘{a}’", "Empty class." : "空的class", "Expected a number and instead saw ‘{a}’.":"应该用数字代替’{a}’", "‘{a}’ should not be greater than ‘{b}’.":"‘{a}’不应该比’{b}’大", "‘hasOwnProperty’ is a really bad name.": "‘hasOwnProperty’是关键字", "‘{a}’ was used before it was defined.":"‘{a}’未定义就已经使用了.", "‘{a}’ is already defined.":"‘{a}’被重复定义", "A dot following a number can be confused with a decimal point.":"数字后面的一个点会被误认为是十进制的小数点", "Confusing minusses" : "容易混淆的负数表达-", "Confusing plusses." : "容易混淆的正数表达+", "Unmatched ‘{a}’." : "无法匹配的’{a}’", "Expected ‘{a}’ to match ‘{b}’ from line {c} and instead saw ‘{d}’.":"在行{c}中需要用’{a}’和’{b}’匹配,用来代替’{d}’", "Unexpected early end of program.":"程序不可预期的提前终止", "A leading decimal point can be confused with a dot: ‘.{a}’.":"‘{a}’前的点容易混淆成小数点", "Use the array literal notation [].":"使用数组的符号 []", "Expected an operator and instead saw ‘{a}’.":"需要用一个符号来代替’{a}’", "Unexpected space after ‘{a}’.":"在’{a}’之后不能出现空格", "Unexpected space before ‘{a}’.":"在’{a}’之前不能出现空格", "Bad line breaking before ‘{a}’.":"在’{a}’之前错误的换行", "Expected ‘{a}’ to have an indentation at {b} instead at {c}.":"‘{a}’需要在{c}而不是{b}处缩进", "Line breaking error ‘{a}’.":"换行错误 ‘{a}’", "Unexpected use of ‘{a}’.":"此处不能用’{a}’", "Bad operand.":"错误的操作数", "Use the isNaN function to compare with NaN.":"使用isNaN来与NaN比较", "Confusing use of ‘{a}’.":"容易混淆的’{a}’的使用", "Read only.":"只读的属性", "‘{a}’ is a function.":"‘{a}’是一个函数", ‘Bad assignment.’:"错误的赋值", "Do not assign to the exception parameter.":"不要给额外的参数赋值", "Expected an identifier in an assignment and instead saw a function invocation.":"在赋值的语句中需要有一个标识符,而不是一个方法的调用", "Expected an identifier and instead saw ‘{a}’ (a reserved word).":"需要有一个标识符,而不是’{a}’(保留字符)", "Missing name in function declaration.":"在方法声明中缺少名称", "Expected an identifier and instead saw ‘{a}’.":"需要有一个标识符,而不是’{a}’", "Inner functions should be listed at the top of the outer function.":"内部函数的声明应该放在此函数的顶部。", "Unreachable ‘{a}’ after ‘{b}’.":"在’{b}’之后无法获取’{a}’", "Unnecessary semicolon.":"不必要的分号", "Label ‘{a}’ on {b} statement.":"将’{a}’放在{b}的声明中", "Label ‘{a}’ looks like a javascript url.":"‘{a}’看上去像一个js的链接", "Expected an assignment or function call and instead saw an expression":"需要一个赋值或者一个函数调用,而不是一个表达式.", "Do not use ‘new’ for side effects.":"不要用’new’语句.", "Unnecessary \"use strict\".":"不必要的\"use strict\".", "Missing \"use strict\" statement.":"缺少\"use strict\"的声明", "Empty block.":"空的模块", "Unexpected /*member ‘{a}’.":"不应出现 /*元素 ‘{a}’.", "‘{a}’ is a statement label.":"‘{a}’是一个声明", "‘{a}’ used out of scope.":"‘{a}’使用超出范围", "‘{a}’ is not allowed.":"不允许使用’{a}’", "‘{a}’ is not defined.":"‘{a}’没有被定义", "Use ‘{a}’ to compare with ‘{b}’.":"使用’{a}’与’{b}’相比", "Variables should not be deleted.":"变量需要被删除", "Use the object literal notation {}.":"使用对象的文字符号 {}", "Do not use {a} as a constructor.":"不要使用{a}作为一个构造对象", "The Function constructor is eval.":"The Function constructor is eval.", "A constructor name should start with an uppercase letter.":"一个构造对象的名称必须用大写字母开头.", "Bad constructor.":"错误的构造对象", "Weird construction. Delete ‘new’.":"构造对象有误,请删除’new’", "Missing ‘()’ invoking a constructor.":"缺少括号()", "Avoid arguments.{a}.":"避免参数.{a}.", "document.write can be a form of eval.":"document.write是eval的一种形式", ‘eval is evil.’:"尽量不要使用eval", "Math is not a function.":"Math不是一个函数", "Missing ‘new’ prefix when invoking a constructor.":"此处缺少了’new’", "Missing radix parameter.":"缺少参数", "Implied eval is evil. Pass a function instead of a string.":"传递一个函数,而不是一个字符串", "Bad invocation.":"错误的调用", "['{a}'] is better written in dot notation.":"['{a}']最好用点.的方式", "Extra comma.":"多余的逗号", "Don’t make functions within a loop.":"不要用循环的方式创建函数", "Unexpected parameter ‘{a}’ in get {b} function.":"在{b}方法中不该用到参数’{a}’", "Duplicate member ‘{a}’.":"重复的’{a}’", "Expected to see a statement and instead saw a block.":"此处应该是语句声明.", "Too many var statements.":"过多var的声明", "Redefinition of ‘{a}’.":"‘{a}’被重复定义", "It is not necessary to initialize ‘{a}’ to ‘undefined’.":"无需将’{a}’初始化为’undefined’", "Expected a conditional expression and instead saw an assignment.":"此处需要一个表达式,而不是赋值语句", "Expected a ‘break’ statement before ‘case’.":"在’case’之前需要有’break’.", "Expected a ‘break’ statement before ‘default’.":"在’default’之前需要有’break’.", "This ‘switch’ should be an ‘if’.":"此处’switch’应该是’if’.", "All ‘debugger’ statements should be removed.":"请删除’debugger’的语句", "‘{a}’ is not a statement label.":"‘{a}’不是一个声明标签.", "Expected an assignment or function call and instead saw an expression.":"需要一个语句或者一个函数调用,而不是一个表达式", "Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.":"函数的声明不能放在类似if的块中,需要放在外部函数的顶部." }
关于怎样在开发过程中使用jshint,个人觉得每次动态的执行 JSHINT(source, options, globals)不方便,建议利用常用的ide提供的jshint插件来检测,比如Eclipse、Netbeans、Webstorm等。 当然我们配置一下options来限定那些检测,那些不检测,详见下面的 JSHint最佳实践。
这里提供了一个简单的利用jshint检验js代码的 页面
当然我们可以借助nodejs来检测javascript代码,见下一节介绍。
执行以下命令安装jshint
npm install jshint -g
安装后就可以用以下命令来检测js代码了
$ jshint myfile.js
配置 configuration
官方是这样描述的:JSHint comes with a default set of warnings but it was designed to be very configurable. There are three main ways to configure your copy of JSHint: you can either specify the configuration file manually via the --config flag, use a special file .jshintrc or put your config into your projects package.json file under the jshintConfig property. In case of .jshintrc, JSHint will look for this file in the current working directory and, if not found, will move one level up the directory tree all the way up to the filesystem root. (Note that if the input comes from stdin, JSHint doesn't attempt to find a configuration file)
中文大概意思是说:配置项提供了三种方式:控制台利用 --config 来设置,创建 .jshintrc 文件,在package.json属性 jshintConfig 中配置。默认.jshintrc跟package.json放在一个目录下,如果没有找到,会向上 查找祖先目录,直至根目录。还有如果在控制台用 --config 来配置,会忽略 .jshintrc 文件中的配置。配置文件是json格式的,例如:
{ "undef": true, "unused": true, "globals": { "MY_GLOBAL": false } }
在代码中的配置,利用注释的方式,每个用逗号隔开。比如
/* jshint undef: true, unused: true */ /* global MY_GLOBAL */
这种配置是局部的,如果在一个function中配置,那么只会影响该function。在代码中的配置项,我们叫做Directives,主要有以下几种
/* jshint strict: true */
/* jslint vars: true */
/* global MY_LIB: false */
当然我们也可以把某一变量列入黑名单确保不会验证他。
/* global -BAD_LIB */
/* exported EXPORTED_LIB */
// Code here will be linted with JSHint. /* jshint ignore:start */ // Code here will be linted with ignored by JSHint. /* jshint ignore:end */
以上用jshint ignore:start 和 jshint ignore:end 可以忽略多行,用jshint ignore:line 可以忽略当前行
ignoreThis(); // jshint ignore:line
下面看看options相关
function main(a, b) { return a == null; }
会输出以下内容(假设文件名为:demo1_use_node.js,下同)
demo1_use_node.js: line 2, col 12, Use '===' to compare with 'null'. 1 error
/*jshint unused:true, eqnull:true */ function main(a, b) { return a == null; }
加上 /*jshint unused:true, eqnull:true */ 后会输入
demo1_use_node.js: line 2, col 14, 'main' is defined but never used. demo1_use_node.js: line 2, col 19, 'b' is defined but never used.
有时我们想忽略警告或错误信息,我们可以这样处理,先看以下例子
"use strict"; /* ... */ // From another file function b() { "use strict"; /* ... */ }
执行jshint后会输出
demo1_use_node.js: line 1, col 1, Use the function form of "use strict". demo1_use_node.js: line 6, col 3, Unnecessary directive "use strict".
我们如果想去掉这些警告时,我们应该首先用命令 jshint --verbose myfile.js 来分析javascript文件,执行后会输出以下内容
demo1_use_node.js: line 1, col 1, Use the function form of "use strict". (W097) demo1_use_node.js: line 6, col 3, Unnecessary directive "use strict". (W034)
后面 W097 和 W034 是某一类的错误code,我们加上以下配置后,将忽略错误警告
/* jshint -W034, -W097 */ "use strict"; /* ... */ // From another file function b() { "use strict"; /* ... */ }
这里需要注意的是,必须是以W开头。如果加上以上配置后,所有这类错误警告将被忽略,但有时我们需要在不同的地方忽略或显示警告,我们可以用以下配置来激活已被忽略的错误警告:/* jshint +W034 */
var y = Object.create(null); // ... 首先忽略 W089警告 /*jshint -W089 */ for (var prop in y) { // ... } //再激活 W089警告 /*jshint +W089 */
对于 Switch statements ,如果没有 break 或 return 会显示以下警告信息
switch (cond) { case "one": doSomething(); // JSHint will warn about missing 'break' here. case "two": doSomethingElse(); }
demo1_use_node.js: line 28, col 16, Expected a 'break' statement before 'case'. (W086)
我们加入以下注释即可忽略警告 /* falls through */
switch (cond) { case "one": doSomething(); /* falls through */ case "two": doSomethingElse(); }
例子代码点击 这里
上面介绍的指令和配置项在web应用中也可以使用。
除了以上两种验证代码方式外,我们还可以在 官方首页中输入代码来动态验证。该页面中可以根据需要设置配置项。
JSHint Options 分为 Enforcing 和 Relaxing,前者默认是不检测的,设为true后才检查,而后者默认是检测的,设为true将忽略。
option | 检测的内容 |
---|---|
bitwise | This option prohibits the use of bitwise operators such as ^ (XOR), | (OR) and others.
Bitwise operators are very rare in JavaScript programs and quite often & is simply a mistyped &&.
如果为真,JSHint会禁用位运算符。 Javascript允许位运算,但是他却没有整型,位运算符要把参与运算的数字从浮点数变为整数,并在运算后再转换回来。这样他们的效率就不如在别的语言中那么高。 /* jshint bitwise: true*/ var a = 12 | 23; console.info(a); |
camelcase | This option allows you to force all variable names to use either camelCase style or UPPER_CASE with underscores.
如果设为true,则js中的变量要求使用驼峰式规则(camelCase或UPPER_CASE) /* jshint camelcase: true*/ var upper_case = '123';//正确的写法为 UPPER_CASE var camelCase = ''; |
curly | This option requires you to always put curly braces around blocks in loops and conditionals.
JavaScript allows you to omit curly braces when the block consists of only one statement, for example: while (day) shuffle();
如果为true,JSHint会要求你在使用if和while等结构语句时加上{}来明确代码块。 Javascript允许在if等结构语句体只有一句的情况下不加括号。不过这样做可能会让你的代码读起来有些晦涩。 /* jshint curly: true*/ var a = false; if (a) console.info(a); |
eqeqeq | This options prohibits the use of == and != in favor of === and !==. The former try to coerce values before comparing them which can lead to some unexpected results.
The latter don't do any coercion so they are generally safer. If you would like to learn more about type coercion in JavaScript,
we recommend Truth, Equality and JavaScript by Angus Croll.
如果为true,JSHint会检验代码中是否都用了 === 或 !==,而不是使用 == 或 !=。 我们建议你在比较0,''(空字符),undefined,null,false和true的时候使用 === 和 !===。 /* jshint eqeqeq: true*/ if (1 == 2) { console.info('宇宙消失了!'); } |
es3 | This option tells JSHint that your code needs to adhere to ECMAScript 3 specification.
Use this option if you need your program to be executable in older browsers—such as Internet Explorer 6/7/8/9—and other legacy JavaScript environments.
是否使用 es3规范,在老的浏览器中是不支持es5和es6的。 |
forin | This option requires all for in loops to filter object's items. The for in statement allows for looping through the names of all of the properties of an
object including those inherited throught the prototype chain.
This behavior can lead to unexpected items in your object so it is generally safer to always filter inherited properties out as shown in the example:
for (key in obj) { if (obj.hasOwnProperty(key)) { // We are sure that obj[key] belongs to the object and was not inherited. } } /* jshint forin: true*/ var Obj1 = function() {}; Obj1.prototype = { property1: '属性一' }; var obj1 = new Obj1(); obj1.property2 = '属性二'; //如果方法体中不加hasOwnProperty判断,会提示错误警告的 for (var p in obj1) { if (obj1.hasOwnProperty(p)) { console.info('自己的属性:' + p); } else { console.info('继承的属性:' + p); } } //简单的继承 var Obj1Sub = function() {}; Obj1Sub.prototype = new Obj1(); Obj1Sub.prototype.constructor = Obj1Sub; Obj1Sub.prototype.property3 = '属性三'; var obj1Sub = new Obj1Sub(); for (var p in obj1Sub) { if (obj1Sub.hasOwnProperty(p)) { console.info('自己的属性:' + p); } else { console.info('继承的属性:' + p); } } For more in-depth understanding of for in loops in JavaScript, read
Exploring JavaScript for-in loops by Angus Croll.
|
freeze | his options prohibits overwriting prototypes of native objects such as Array, Date and so on.
如果设为true,当复写对象prototype存在的方法时,会提示错误警告。 /* jshint freeze:true */ Array.prototype.count = function (value) { return 4; }; // -> Warning: Extending prototype of native object: 'Array'. |
immed | This option prohibits the use of immediate function invocations without wrapping them in parentheses. Wrapping parentheses assists readers of your code in understanding that the expression is the result of a function, and not the function itself. |
indent | This option enforces specific tab width for your code. For example, the following code will trigger a warning on line 4:
/*jshint indent:4 */ var cond = true; if (cond) { console.info('d'); }indent设为 4 表示在第四行会有一个错误提示信息,注意是从/*jshint indent:4 */ 算起的,从1开始,而不是从0 |
latedef | This option prohibits the use of a variable before it was defined. JavaScript has function scope only and, in addition to that,
all variables are always moved—or hoisted— to the top of the function. This behavior can lead to some very nasty bugs and that's why it is safer to always use variable only after
they have been explicitly defined.
Setting this option to "nofunc" will allow function declarations to be ignored.
For more in-depth understanding of scoping and hoisting in JavaScript, read JavaScript Scoping and Hoisting
by Ben Cherry.
latedef设为true,再调用变量或函数时,必须确保这些变量和函数在调用之前已经声明过,也就是说声明代码必须写在调用代码的前面,而不能写在后面。可以设置nofunc值忽略函数的位置而只检查变量。 /*jshint latedef: nofunc */ latedefFun(); function latedefFun() {} console.info(latedefVar); var latedefVar = '1'; |
newcap | This option requires you to capitalize names of constructor functions. Capitalizing functions that are intended to be used with new operator is just
a convention that helps programmers to visually distinguish constructor functions from other types of functions to help spot mistakes when using this.
Not doing so won't break your code in any browsers or environments but it will be a bit harder to figure out—by reading the code—if the function was supposed
to be used with or without new. And this is important because when the function that was intended to be used with new is used without it, this will point to
the global object instead of a new object.
newcap 设为true,是指如果一个函数作为构造函数时,并且在其他地方使用了new操作符实例化一个变量,那么这个构造函数中不要使用this操作符。 /*jshint newcap: true */ function newcapFun() { this.a = 'a'; } var newcapCon = new newcapFun(); |
noarg | This option prohibits the use of arguments.caller and arguments.callee. Both .caller and .callee make quite a few optimizations impossible so they
were deprecated in future versions of JavaScript. In fact, ECMAScript 5 forbids the use of arguments.callee in strict mode.
如果是true,则不允许使用arguments.caller和arguments.callee。 /*jshint noarg: true */ function noargFun() { console.info(arguments.callee); console.info(arguments.caller); } |
noempty | This option warns when you have an empty block in your code. JSLint was originally warning for all empty blocks and we simply made it optional.
There were no studies reporting that empty blocks in JavaScript break your code in any way.
如果是true,不允许有空的代码块,例子待实现 |
nonew | This option prohibits the use of constructor functions for side-effects. Some people like to call constructor functions without assigning its result to any variable:
new MyConstructor();There is no advantage in this approach over simply calling MyConstructor since the object that the operator new creates isn't used anywhere so you should generally avoid constructors like this one. 如果为true,则不允许不做赋值的构造函数,例如new UIWindow(); /*jshint nonew: true */ function nonewFun() {} new nonewFun(); |
plusplus | This option prohibits the use of unary increment and decrement operators. Some people think that ++ and -- reduces the quality of their coding styles
and there are programming languages—such as Python—that go completely without these operators.
如果是true,则不允许使用 ++ 或者 -- 的操作 /*jshint plusplus: true */ var plus = 10; plus++; ++plus; |
quotmark | This option enforces the consistency of quotation marks used throughout your code.
It accepts three values: true if you don't want to enforce one particular style but want some consistency,
"single" if you want to allow only single quotes and "double" if you want to allow only double quotes.
有3种值:如果是true,则表示要求引号一致;如果是single,则表示只允许使用单引号;如果是double,则表示只允许双引号 /*jshint quotmark: true */ var quotmark1 = ""; var quotmark2 = ''; |
undef | This option prohibits the use of explicitly undeclared variables. This option is very useful for spotting leaking and mistyped variables.
/*jshint undef:true */ function test() { var myVar = 'Hello, World'; console.log(myvar); }If your variable is defined in another file, you can use /*global ... */ directive to tell JSHint about it. 设为true,如果变量没有定义会输出错误警告信息。 |
unused | This option warns when you define and never use your variables. It is very useful for general code cleanup, especially when used in addition to undef.
/*jshint unused:true */ function test(a, b) { var c, d = 2; return a + d; } test(1, 2); // Line 3: 'b' was defined but never used. // Line 4: 'c' was defined but never used.In addition to that, this option will warn you about unused global variables declared via /*global ... */ directive. This can be set to vars to only check for variables, not function parameters, or strict to check all variables and parameters. The default (true) behavior is to allow unused parameters that are followed by a used parameter. 设为true,表示如果声明了变量,但没有使用,会提示错误警告的。 |
strict |
This option requires all functions to run in ECMAScript 5's strict mode. Strict mode
is a way to opt in to a restricted variant of JavaScript. Strict mode eliminates some JavaScript pitfalls that didn't cause errors by changing them to produce errors.
It also fixes mistakes that made it difficult for the JavaScript engines to perform certain optimizations. Note: This option enables strict mode for function scope only. It prohibits the global scoped strict mode because it might break third-party widgets on your page. If you really want to use global strict mode, see the globalstrict option. 设为true,表明SHint会要求你使用use strict;语法,strict是 ECMAScript 5定义的。他对一些js代码做了限制,比如 var o = { p: 1, p: 2 }; 会提示错误的。 |
trailing | This option makes it an error to leave a trailing whitespace in your code. Trailing whitespaces can be source of nasty bugs with multi-line strings in JavaScript:
// This otherwise perfectly valid string will error if // there is a whitespace after \ /*jshint trailing:true */ var str = "Hello \ World"; 如果设为 true,以上代码会报错的。 |
maxparams |
This option lets you set the max number of formal parameters allowed per function: /*jshint maxparams:3 */ function login(request, onSuccess) { // ... } // JSHint: Too many parameters per function (4). function logout(request, isManual, whereAmI, onSuccess) { // ... }设置function的参数最大个数 |
maxdepth | This option lets you control how nested do you want your blocks to be:
/*jshint maxdepth:2 */ function maxdepthFn(meaning) { var day = true; var tired = true; var shuffle = function(){ tired = false; }; var sleep = function(){ console.info(1); }; if (meaning === 42) { while (day) { shuffle(); if (tired) { // JSHint: Blocks are nested too deeply (3). sleep(); } } } }限定最大嵌套数 |
maxstatements | This option lets you set the max number of statements allowed per function:
/*jshint maxstatements:4 */ function maxstatementsFn() { var i = 0; var j = 0; // Function declarations count as one statement. Their bodies // don't get taken into account for the outer function. function inner() { var i2 = 1; var j2 = 1; return i2 + j2; } j = i + j; return j; // JSHint: Too many statements per function. (5) }限制函数中表达式的最多行数 |
maxcomplexity | This option lets you control cyclomatic complexity throughout your code.
Cyclomatic complexity measures the number of linearly independent paths through a program's source code. Read more about
cyclomatic complexity on Wikipedia.
控制函数的复杂度 |
maxlen | This option lets you set the maximum length of a line. 设置每行最大长度。 |
option | 检测的内容 |
---|---|
asi | This option suppresses warnings about missing semicolons. There is a lot of FUD about semicolon spread by quite a few people in the community.
The common myths are that semicolons are required all the time (they are not) and that they are unreliable.
JavaScript has rules about semicolons which are followed by all browsers so it is up to you to decide whether you should or should not use semicolons in your code.
For more information about semicolons in JavaScript read An Open Letter to JavaScript Leaders Regarding Semicolons by Isaac Schlueter and JavaScript Semicolon Insertion 默认JSHint会要求在每个语句后面加上分号(需要加的),如果设为false,则忽略检测。 var a = '' var b = '' //line 1, col 11, Missing semicolon. (W033) //line 2, col 11, Missing semicolon. (W033) |
boss | This option suppresses warnings about the use of assignments in cases where comparisons are expected.
More often than not, code like if (a = 10) {} is a typo. However, it can be useful in cases like this one:
You can silence this error on a per-use basis by surrounding the assignment with parenthesis, such as: 很霸气的选项,如果为真,那么JSHint会允许在if,for,while里面编写赋值语句。 一般来说,我们会在循环、判断等语句中加入值的比较来做语句的运行条件,有时候会把==错写成赋值的=,通常,JSHint会把这个认定为一个错误,但是开启这个选项的化,JSHint就不会检查判断条件中的赋值 , 你是boss,你说的算:)。 if (a = 10) {} for (var i = 0, person; person = people[i]; i++) {} for (var i = 0, person; (person = people[i]); i++) {} //line 1, col 11, Expected a conditional expression and instead saw an assignment. (W084) //line 2, col 43, Expected a conditional expression and instead saw an assignment. (W084) |
debug |
This option suppresses warnings about the debugger statements in your code.
默认是不允许出现 debugger语句的 debugger; //line 1, col 1, Forgotten 'debugger' statement? (W087) |
eqnull |
This option suppresses warnings about == null comparisons. Such comparisons are often useful when you want to check if a variable is null or undefined.
如果为true,JSHint会允许使用"== null"作比较。 == null 通常用来判断一个变量是undefined或者是null(当时用==,null和undefined都会转化为false)。默认是不允许的。 var eqnullStr = ''; if(eqnullStr == null){ console.info(1); } //line 1, col 9, Use '===' to compare with 'null'. (W041) |
esnext | This option tells JSHint that your code uses ECMAScript 6 specific syntax. Note that these features are not finalized yet and not all browsers implement them. More info:Draft Specification for ES.next (ECMA-262 Ed. 6) 设置该值为true,告诉JSHint用 ECMAScript 6 规范检测js代码。 |
evil | This option suppresses warnings about the use of eval.
The use of eval is discouraged because it can make your code vulnerable to various injection attacks and it makes it hard for JavaScript interpreter to do certain optimizations.
如果为真,JSHint会允许使用eval eval提供了访问Javascript编译器的途径,这有时很有用,但是同时也对你的代码形成了注入攻击的危险,并且会对debug造成一些困难。 记住,Function构造函数也是另一个‘eval’,另外,当传入的参数是字符串的时候,setTimeout和setInterval也会类似于eval。默认JSHint是不允许使用eval的。 eval('var aa = "bb";'); setTimeout('function(){console.info(1);}',100); var fn = new Function(); //line 1, col 1, eval can be harmful. (W061) //line 2, col 1, Implied eval. Consider passing a function instead of a string. (W066) //line 3, col 22, The Function constructor is a form of eval. (W054) //line 1, col 9, Missing name in function declaration. (W025) |
expr | This option suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls. Most of the time, such code is a typo. However, it is not forbidden by the spec and that's why this warning is optional. |
funcscope | This option suppresses warnings about declaring variables inside of control structures while accessing them later from the outside.
Even though JavaScript has only two real scopes—global and function—such practice leads to confusion among people new to the language and hard-to-debug bugs. This is why,
by default, JSHint warns about variables that are used outside of their intended scope.
function test() { if (true) { var x = 0; } x += 1; } // line 5, col 3, 'x' used out of scope. (W038) 上面的写法会提示错误信息的,虽然js只有全局和function级别的scope,但我们还是避免上面的写法,让人看了比较不爽。 |
globalstrict | This option suppresses warnings about the use of global strict mode. Global strict mode can break third-party widgets so it is not recommended. For more info about strict mode see the strict option. 全局是否用strict模式 |
iterator |
This option suppresses warnings about the __iterator__ property. This property is not supported by all browsers so use it carefully.
默认时,对于使用 __iterator__ property 会提示错误信息的。关于javascript的版本信息,可以参考这里 JavaScript版本迷局 和 JavaScript IE中 JavaScript 版本信息 function iteratorFn (){} var iterator = new iteratorFn(); console.info(iterator.__iterator__); //line 3, col 35, '__iterator__' is only available in JavaScript 1.7. (W104) |
lastsemic | This option suppresses warnings about missing semicolons, but only when the semicolon is omitted for the last statement in a one-line block:
This is a very niche use case that is useful only when you use automatic JavaScript code generators.
如果设为true,则只检测一行最后的分号,对于中间的分号将不检测,默认检测所有的分号 var name = (function() { return 'Anton' }()); //line 1, col 40, Missing semicolon. (W033) |
laxbreak | This option suppresses most of the warnings about possibly unsafe line breakings in your code.
It doesn't suppress warnings about comma-first coding style. To suppress those you have to use laxcomma (see below).
如果为true,JSHint则不会检查换行。 Javascript会通过自动补充分号来修正一些错误,因此这个选项可以检查一些潜在的问题。 |
laxcomma | This option suppresses warnings about comma-first coding style:
会自动检测逗号在一行的情况,设为true则忽略。 var obj = { name: 'Anton' , handle: 'valueof' , role: 'SW Engineer' }; //line 3, col 3, Comma warnings can be turned off with 'laxcomma'. (I001) //line 2, col 11, Bad line breaking before ','. (W014) //line 3, col 13, Bad line breaking before ','. (W014) |
loopfunc | This option suppresses warnings about functions inside of loops. Defining functions inside of loops can lead to bugs such as this one:
不用在循环中定义function var nums = []; for (var i = 0; i < 10; i++) { nums[i] = function (j) { return i + j; }; } nums[0](2); // Prints 12 instead of 2To fix the code above you need to copy the value of i: var nums = []; for (var i = 0; i < 10; i++) { (function (i) { nums[i] = function (j) { return i + j; }; }(i)); } 以上实现会输出错误警告信息 var nums = []; for (var i = 0; i < 10; i++) { nums[i] = function (j) { return i + j; }; } nums[0](2); var nums = []; for (var i = 0; i < 10; i++) { (function (i) { nums[i] = function (j) { return i + j; }; }(i)); } //line 5, col 4, Don't make functions within a loop. (W083) //line 15, col 4, Don't make functions within a loop. (W083) |
moz | This options tells JSHint that your code uses Mozilla JavaScript extensions. Unless you develop specifically for the Firefox web browser you don't need this option.
More info: New in JavaScript 1.7
当使用mozilla javascript 扩展表达式是会提示警告信息的。 |
multistr | This option suppresses warnings about multi-line strings. Multi-line strings can be dangerous in JavaScript because all hell breaks loose if you accidentally
put a whitespace in between the escape character (\) and a new line.
Note that even though this option allows correct multi-line strings, it still warns about multi-line strings without escape characters or with anything in between the escape character and a whitespace. /*jshint multistr:true */ var text = "Hello\ World"; // All good. text = "Hello World"; // Warning, no escape character. text = "Hello\ World"; // Warning, there is a space after \默认下,JSHint不建议使用\来处理多行的字符串,我们可以利用数组来处理。 |
notypeof | This option suppresses warnings about invalid typeof operator values.
This operator has only a limited set of possible return values.
By default, JSHint warns when you compare its result with an invalid value which often can be a typo.
Do not use this option unless you're absolutely sure you don't want these checks. // 'fuction' instead of 'function' var a = ''; if (typeof a == "fuction") { // Invalid typeof value 'fuction' /* ... */ } //line 3, col 14, Invalid typeof value 'fuction' (W122)如果使用typeof语句时,表达式不是javascript规定的返回值,则会显示错误警告信息。关于typeof返回的值可以参考这里 |
proto | This option suppresses warnings about the __proto__ property. 如果使用 __proto__ property 会显示错误警告 |
scripturl | This option suppresses warnings about the use of script-targeted URLs—such as javascript:.... |
smarttabs | This option suppresses warnings about mixed tabs and spaces when the latter are used for alignmnent only.
The technique is called SmartTabs.
当混合使用 tabs 和 spaces时会发出警告 |
shadow | This option suppresses warnings about variable shadowing i.e.
declaring a variable that had been already declared somewhere in the outer scope.
在外层声明的变量,在里层代码就不要声明了,否则会提示警告信息。 |
sub | This option suppresses warnings about using [] notation when it can be expressed in dot notation: person['name'] vs. person.name.
对于能使用下标的情况,尽量使用,关键字或不可以使用下标的情况下,可以使用[]形式。下面例子属性 'c-d' 不会提示错误警告信息,而b会提示。 var a = { b: '', 'c-d': '' }; console.info(a['b']); console.info(a['c-d']); //line 5, col 15, ['b'] is better written in dot notation. (W069) |
supernew | This option suppresses warnings about "weird" constructions like new function () { ... } and new Object;.
Such constructions are sometimes used to produce singletons in JavaScript:
var singleton = new function() { this.publicMethod = function () {}; this.publicMethod2 = function () {}; }; //line 1, col 17, Weird construction. Is 'new' unnecessary? (W057) //line 4, col 1, Missing '()' invoking a constructor. (W058)当书写怪异的javascript语句时,会发出提示警告 |
validthis | This option suppresses warnings about possible strict violations when the code is running in strict mode and you use this in a non-constructor function.
You should use this option—in a function scope only—when you are positive that your use of this is valid in the strict mode (for example,
if you call your function using Function.call). Note: This option can be used only inside of a function scope. JSHint will fail with an error if you will try to set this option globally. |
jsHint默认提供了以下 Environments 的设置
browser | This option defines globals exposed by modern browsers: all the way from good old document and navigator to the HTML5 FileReader and other new developments in the browser world. Note: This option doesn't expose variables like alert or console. See option devel for more information. |
couch | This option defines globals exposed by CouchDB. CouchDB is a document-oriented database that can be queried and indexed in a MapReduce fashion using JavaScript. |
devel | This option defines globals that are usually used for logging poor-man's debugging: console, alert, etc. It is usually a good idea to not ship them in production because, for example, console.log breaks in legacy versions of Internet Explorer. |
dojo | This option defines globals exposed by the Dojo Toolkit. |
jquery | This option defines globals exposed by the jQuery JavaScript library. |
mootools | This option defines globals exposed by the MooTools JavaScript framework. |
node | This option defines globals available when your code is running inside of the Node runtime environment. Node.js is a server-side JavaScript environment that uses an asynchronous event-driven model. This option also skips some warnings that make sense in the browser environments but don't make sense in Node such as file-level use strict pragmas and console.log statements. |
nonstandard | This option defines non-standard but widely adopted globals such as escape and unescape. |
phantom | This option defines globals available when your core is running inside of the PhantomJS runtime environment. PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG. |
prototypejs | This option defines globals exposed by the Prototype JavaScript framework. |
rhino | This option defines globals available when your code is running inside of the Rhino runtime environment. Rhino is an open-source implementation of JavaScript written entirely in Java. |
worker | This option defines globals available when your code is running inside of a Web Worker. Web Workers provide a simple means for web content to run scripts in background threads. |
wsh | This option defines globals available when your code is running as a script for the Windows Script Host. |
yui | This option defines globals exposed by the YUI JavaScript framework. |
首先看几篇参考文章