处理循环变量的重复声明警告
Dealing with duplicate declaration warning for loop variables
请考虑以下代码:
for (var i=0; i<100; i++) {
// your code here
}
// some other code here
for (var i=0; i<500; i++) {
// custom code here
}
任何像样的 lint 工具(jslint、jshint 或内置 IDE)都会发出警告 - duplicate declaration of variable i
.这可以通过使用具有另一个名称(k
,j
)的变量或将声明移动到顶部来解决:
var i; // iterator
for (i=0; i<100; i++) {}
for (i=0; i<500; i++) {}
我不喜欢这两种变体 - 我通常不会在顶部进行声明(即使我这样做了,我也不希望看到有辅助变量 - i
、j
、k
),在这些示例中确实没有什么不好的事情来更改变量的名称。
虽然我确实想要一个巨大的警告,以防我写这样的东西:
for (var i=0; i<100; i++) {
for (var i=0; i<500; i++) {} // now that's bad
}
你对这种情况有什么看法?
JavaScript 有许多结构,看起来像其他计算机语言中的知名结构。对于JavaScript来说,以大多数其他计算机语言的另一种方式解释结构是危险的。
如果有人对 JavaScript 不够了解(顺便说一下,这是常见的情况)看到这样的结构
for (var i=0; i<100; i++) {
// your code here
}
或在块中看到变量的声明
{
var i;
//some code
{
var j;
// some code
}
}
然后大多数读者会认为将定义块级变量。JavaScript 没有块级变量。所有变量都将被解释为函数级别定义。
因此,如果代码不仅仅是一些仅编写 5 分钟的测试代码,我从不在代码中定义变量。主要原因是我不想编写代码并使用可能被误解的语言结构。
顺便说一下,JSLint 发现块内部变量的定义如此糟糕,以至于它停止了代码分析的处理。没有可以更改此行为的 JSLint 选项。我发现 JSLint 的行为不好,但我同意循环内变量for
声明是不好的,因为它会被大多数人读取为带有局部循环变量的代码,这是不正确的。
如果您使用
for (var i=0; i<100; i++) {
// your code here
}
// some other code here
for (var i=0; i<500; i++) {
// custom code here
}
然后 JavaScript 会为你移动函数开头的所有变量声明。所以代码将作为
var i = undefined, i = undefined; // duplicate declaration which will be reduced
// to one var i = undefined;
for (i=0; i<100; i++) {
// your code here
}
// some other code here
for (i=0; i<500; i++) {
// custom code here
}
因此,请考虑代码的其他读者。不要使用任何可能以错误方式解释的结构。
let
关键字是在JavaScript 1.7中引入的。请在此处找到 MDN 文档
将 var
替换为 for loop
内部的 let
解决了这个问题,现在可以在循环范围内声明局部变量。在这里查看stackoverlow社区解释:使用"let"和"var"来声明变量有什么区别?
未来的代码:
for (let i = 0; i < someVar.length; i++) {
// do your thing here
}
我建议将循环包含在自执行函数中,这些函数的名称告诉您循环在做什么。这有效地为循环提供了块范围。例如:
var users = response['users']
;(function appendUsers(){
for (var i = 0; i < users.length; i++) {
var user = users[i]
var userEmail = user['email']
var userId = user['id']
/* etc */
}
})() // appendUsers
如果这样做:
var i
for (i = 0; i < someVar.length; i++) {
for (i = 0; i < someOtherVar.length; i++) {
// This is a bug that a validator will not notice.
}
}
另一方面:
for (var i = 0; i < someVar.length; i++) {
for (var i = 0; i < someOtherVar.length; i++) {
// This is a bug that a validator will warn you about.
}
}
for (var i = 0; i < yetAnotherVar.length; i++) {
// It will also warn you about this, but so what?
}
您可以停止将i
用作迭代器:
for (var companyIndex = 0; companyIndex < companies.length; companyIndex++) {
var company = companies[companyIndex]
}
如果你使用的是jQuery,你可以使用它的jQuery.each()
方法:
$.each(someVar, function(i, value){
// etc
})
如果您希望 IE8 及更早版本正常工作,则不能使用 Array.prototype.forEach()
,除非您添加 Polyfill 代码或类似代码。
我倾向于使用数组内置函数,例如map,filter和forEach,从而完全避免了这个问题。这也会自动为您提供范围循环体,这也非常有用。
如果使用这些与用例不匹配,我通常会求助于 top 声明,这样我就可以避免您提到的问题。
- Dojo不解析自定义小部件的模板html中的小部件声明性
- chrome扩展更改主机/域警告
- 直接在函数声明上使用function.prototype.bind
- 获取HTML属性中CSS声明的值
- 对API数据使用声明性绑定
- 如何永久停止jshint'只读'警告/错误
- 可以Resharper在我的javascript函数声明中添加分号
- 如何为排除无穷大和NaN的数字声明Flow类型
- 此行是否包含函数声明
- Javascript以不同的方式声明数字
- 如何使用php文件中的GET来获取我在.js文件中声明的变量
- JShint-.jshintrc中的ES6有esversion,但仍收到警告(使用atom)
- 使用同一对象中的其他变量声明变量
- 处理循环变量的重复声明警告
- 如何抑制“;警告-重新声明的变量:“;在闭包编译器中
- 当在模板中使用未声明的指令时,是否有任何方法可以使angular警告我
- 为什么我得到“构造函数必须在声明时初始化”谷歌闭包编译器警告
- jlint警告' var counter的重新声明'是必要的吗?
- 为什么ReSharper在声明函数之前会警告它被使用
- JSLint -未声明'警告