大部分JSLint的行为都在JSLint指令页面中解释了。我从现在开始将其称为JIP。
没有被JIP解释的行为大多在Crockford的JavaScript编程语言代码约定中得到了解释。我从现在开始将其称为CCJPL。
按照列表进行:
1)JSLint为什么会在不包含"use strict";
时发出错误信号?
因为严格模式可以执行许多良好的实践;而JSLint也是关于执行良好实践的,所以这是它的行为。查看"use strict"
启用的内容有助于澄清此问题。我只是按照Resig的博客文章中的列表进行操作,因此应该给予相应的功劳。我并未对它所做的每个功能进行评论,因为我不确定Crockford每个功能的确切原因。
- 在赋值前必须使用
var
声明变量:这可以防止隐含的全局变量出现。Crockford认为全局变量是邪恶的,这有助于消除你没有显式设置的全局变量。
- 它限制了
eval
,这被JIP视为邪恶。
- 它禁用了
with
语句。这被Crockford认为是有害的。
我只省略了严格模式的两个功能:修改delete
语句的行为和覆盖arguments
变量。我不知道Crockford是否同意或反对这两个事情,但考虑到他帮助创建了ECMAScript 5标准,我倾向于认同。
2) 为什么应该使用单个var
在函数内部进行变量声明?
首先,任何未经var
声明而定义的变量都是隐含全局变量,这根据JIP可以“掩盖拼写错误的名称和其他问题”。因此,这是需要var
的原因。
关于要求只有一个var
,JavaScript引擎会自动将所有变量声明提升到它们作用域的顶部,所以我的猜测是Crockford希望开发人员能对这种行为有敏锐的认识。除此之外,这可能只是一种风格上的选择。你更喜欢下面两段代码中的哪一段:
var a, b, c;
或者
var a; var b; var c;
我的猜测是Crockford认为多个var
很丑。在这一点上我同意他的看法。
具有讽刺意味的是,根据CCJPL,他实际上建议将所有变量声明放在不同的行上,并附带注释。在这方面,JSLint与他的看法不同!
3)为什么需要在function ()
之间加上空格?
这仅适用于匿名函数。根据CCJPL,原因是:
如果函数文字是匿名的,则应该在单词“function”和左括号“(”之间有一个空格。如果省略了空格,则可能会出现函数名称为function的错误读取。
当我深入学习JavaScript时,我虔诚地开始遵循Crockford的惯例……但是我的逻辑部分说,如果您的代码将函数命名为function
,那么它可能急需重新编写。(更不用说在JavaScript中,这是一个SyntaxError
,因为function
是一个关键字。)
4)为什么不能使用continue
?
引用CCJPL的话:
它往往会混淆函数的控制流程。
并不是一个详细的回答,但我在互联网上看到过将其与goto进行比较的争论。您可以理解为这样。
5)++和--有什么问题?
如
JIP所述:
增量(++)和减量(- -)运算符已知通过鼓励过度狡猾而导致糟糕的代码。除了错误的体系结构之外,它们仅次于启用病毒和其他安全威胁。此外,预增量/后增量混淆可能会产生极难诊断的差一错误。
6)为什么我们不能使用逗号运算符“,”(除了在for语句的初始化和增量部分中)?
JIP的另一个详细解释:
逗号运算符可能会导致过度狡猾的表达式。它还可以掩盖一些编程错误。
这真是太遗憾了,因为正如您链接的博客文章所示,逗号运算符确实可以在某些情况下增加代码的清晰度。
您会注意到Crockford的许多惯例都有一个共同的基本主题:易于理解、可读的代码。这只是其中的另一个例子。许多惯例都集中于拒绝访问“狡猾”的表达式。
但我认为描述这些表达式的真正词语应该是“简洁”,这并不一定是坏事,但如果使用不当就可能会有害。Crockford的规则有时会尝试通过删除一些工具来消除错误使用的简洁性,即使在某些情况下它们有合法的用途。
7)为什么每个语句都应该以“;”结尾?
再次引用
JIP的话:
JavaScript使用类似C的语法,需要使用分号来分隔某些语句。 JavaScript尝试使用分号插入机制使这些分号变成可选项。这很危险,因为它可能掩盖错误。
像C一样,JavaScript有++和--和(运算符可以是前缀或后缀。分号进行了区分。
通常,我发现Crockford解释中“可能掩盖错误”的部分相当广泛和模糊,但分号插入确实是一个我完全同意的领域。在每个语句后使用显式分号比冒险缩小危险的分号插入范围更容易。
以下是维基百科
JavaScript Syntax页面上出现分号插入错误的经典示例:
return
a + b;
// Returns undefined. Treated as:
// return;
// a + b;
如果您使用像这篇博客文章中的代码一样的对象字面量(一种相当常见的大括号样式),那么它也可能会使您困扰:
function shoeFactory() {
return
{
shoeSize: 48
};
}
var shoe = shoeFactory();
console.log(shoe);
来自上述维基百科文章的另一个示例:
a = b + c
(d + e).foo()
我从来没有因为要添加显式分号而感到困扰。在编写几乎任何代码时,它们对我来说都非常自然。事实上,即使在Python中不需要分号,我经常发现自己还是会加上分号。
在这种情况下,我非常赞同Crockford的观点。我认为一次关于分号插入的调试会议可能会让大多数人相信,将它们放在代码中会更容易。