处理循环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 。 这可以通过使用另一个名称( kj )的variables或将声明移动到顶部来解决:

 var i; // iterator for (i=0; i<100; i++) {} for (i=0; i<500; i++) {} 

我不喜欢这两种变体 – 我不通常在顶部做声明(即使我做了也不想看到辅助variables – ijk ),在这些例子中真的没什么不好的改变variables的名字。

虽然我想要一个巨大的警告,如果我写这样的事情:

 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 } 

或者在块中看到variables的声明

 { var i; //some code { var j; // some code } } 

那么大多数读者会认为块级variables将被定义。 JavaScript没有块级variables。 所有variables将被解释为定义的function级别。

所以我从不在代码中定义variables,如果代码不只是一些testing代码,只会写5分钟。 主要原因是我不想编写代码,使用可能会被误解的语言结构

顺便说一句,JSLint发现块内部的variables定义了这样糟糕的风格,停止了代码分析的处理。 没有可以改变这种行为的JSLint选项。 我发现JSLint的行为不好,但是我同意在for循环中声明variables是不好的,因为它会被大多数人读为带有本地循环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 } 

那么JavaScript会在函数的开头为你移动所有variables的声明。 所以代码将是

 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中引入。 请在这里findMDN文档

replacevar let inside for loop解决了这个问题,现在可以在循环范围内声明局部variables。 在这里查看stackoverlow社区说明: 使用“let”和“var”声明一个variables有什么区别?

未来的代码:

 for (let i = 0; i < someVar.length; i++) { // do your thing here } 

我build议把你的循环放在自执行的函数中,这些函数的名字告诉你循环在做什么。 这有效地给块的范围循环。 例如:

 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 }) 

除非添加了Polyfill代码或类似的东西,否则你不能使用Array.prototype.forEach()

我倾向于使用数组内置的函数,比如map,filter和forEach,从而完全避免了这个问题。 这也自动给你的范围循环体也是非常有用的。

如果使用那些不符合用例的情况下,我通常会诉诸顶级声明,所以我可以避免你提到的问题。

这里的最佳实践应该是良好的编程风格:

一个程序应该用简短的function来构build,这将会起到一点作用。 通常情况下,如果你循环,你做一些特殊的事情应该站在自己的function。 最后每个函数都有自己的范围,这样重复声明问题就不存在了。

 function myApp() { magicLoopAction(); someOtherMagicStuff(); } function magicLoopAction() { for (var i = 0; i < 42; i++) { // whoopwhoop } } function someOtherMagicStuff() { for (var i = 0; i < 69; i++) { // lint is happy and proud on you } }