javascript 处理循环变量的重复声明警告

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10801747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 11:04:37  来源:igfitidea点击:

Dealing with duplicate declaration warning for loop variables

javascriptjslint

提问by Ilya Tsuryev

Consider the following code:

考虑以下代码:

for (var i=0; i<100; i++) {
    // your code here
}
// some other code here
for (var i=0; i<500; i++) {
    // custom code here
}

Any decent lint tool (jslint, jshint or built in IDE) will tell warning - duplicate declaration of variable i. This can be solved by using variable with another name (k, j) or moving declaration to the top:

任何合适的 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 am not fond of both variants - I don't make declarations at the top usually (and even if I did I wouldn't want see there helper variables - i, j, k) and really nothing bad is going on in those examples to change variables' names for.

我不喜欢这两种变体 - 我通常不会在顶部进行声明(即使我这样做了,我也不希望看到辅助变量 - i, j, k)并且在这些示例中确实没有任何不好的事情发生来更改变量' 的名字。

Though I do want a huge warning in case I write something like this:

虽然我确实想要一个巨大的警告,以防我写这样的东西:

for (var i=0; i<100; i++) {
    for (var i=0; i<500; i++) {} // now that's bad
}

What's your approach to such cases?

您对此类案件的处理方式是什么?

回答by Oleg

JavaScript has many constructions which look like well-known constructions in other computer languages. It's dangerous for JavaScript to interpret the construction in anotherway as most other computer languages.

JavaScript 有许多看起来像其他计算机语言中众所周知的结构的结构。JavaScript 以与大多数其他计算机语言一样的另一种方式解释构造是危险的。

If somebody who doesn't know JavaScript good enough (the common case by the way) sees the construction like

如果对 JavaScript 不够了解的人(顺便说一下,常见的情况)会看到这样的结构

for (var i=0; i<100; i++) {
    // your code here
}

or sees declaration of the variable in the block

或查看块中变量的声明

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

then most readers will think that block level variableswill be defined. JavaScript don't have block level variables. All variables will be interpreted as function level defined.

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

So I never define variables inside of the codeif the code is not just some test code which will be written for 5 min only. The main reason is that I don't want to write code and use language constructions which could be misunderstood.

因此如果代码不仅仅是一些仅编写 5 分钟的测试代码,我就不会在代码中定义变量。主要原因是我不想编写代码和使用可能被误解的语言结构

By the way JSLint finds defining of variables inside of block such bad style that it stop processing of the code analysis. There are no JSLint options which could change this behavior. I find the behavior of JSLint not good, but I agree that declaration of variables inside of forloop is bad because it will be read by most persons as code with localloop variables, which is incorrect.

顺便说一下,JSLint 发现块内变量的定义如此糟糕,以至于它停止了代码分析的处理。没有可以改变这种行为的 JSLint 选项。我发现 JSLint 的行为不好,但我同意在for循环内声明变量是不好的,因为它会被大多数人读取为带有局部循环变量的代码,这是不正确的。

If you use

如果你使用

for (var i=0; i<100; i++) {
    // your code here
}
// some other code here
for (var i=0; i<500; i++) {
    // custom code here
}

then JavaScript moves all declarations of variables at the beginning of the functionfor you. So the code will be as

然后 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
}

So please think about other readers of the code. Don't use any constructions which could be interpreted in the wrong way.

所以请考虑代码的其他读者。不要使用任何可能以错误方式解释的结构。

回答by Said Kholov

letkeyword is introduced in javascript 1.7. Please find MDN documentation here

let关键字是在 javascript 1.7 中引入的。请在此处找到 MDN 文档

Replacing varto letinside for loopsolves the problem and now one can declare local variable inside the scope of a loop. Check out stackoverlow community explanation here: What's the difference between using "let" and "var" to declare a variable?

替换varletinsidefor loop解决了问题,现在可以在循环范围内声明局部变量。在此处查看 stackoverlow 社区解释:使用“let”和“var”声明变量有什么区别?

Code from future:

来自未来的代码:

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

回答by Vladimir Kornea

I recommend enclosing your loops within self-executing functions whose names tell you what the loop is doing. This effectively gives block scope to the loop. For example:

我建议将您的循环包含在自执行函数中,这些函数的名称会告诉您循环在做什么。这有效地为循环提供了块范围。例如:

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

If you do this:

如果你这样做:

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

On the other hand:

另一方面:

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

You can stop using ias an iterator:

您可以停止使用i作为迭代器:

for (var companyIndex = 0; companyIndex < companies.length; companyIndex++) {
    var company = companies[companyIndex]
}

If you're using jQuery anyway, you can use its jQuery.each()method:

如果你无论如何都在使用 jQuery,你可以使用它的jQuery.each()方法:

$.each(someVar, function(i, value){
    // etc
})

You can't use Array.prototype.forEach()if you want IE8 and earlier to work, unless you add the Polyfill codeor similar.

Array.prototype.forEach()如果您希望 IE8 及更早版本工作,则不能使用,除非您添加Polyfill 代码或类似代码

回答by Exelian

I tend the use the array built-in functions, such as map, filter and forEach, thus avoiding the issue altogether. This also automatically gives you scope loop bodies which is also quite useful.

我倾向于使用数组内置函数,例如 map、filter 和 forEach,从而完全避免这个问题。这也会自动为您提供范围循环体,这也非常有用。

If using those doesn't match the use case I usually resort to top declaration, simply so I can avoid the issues you mentioned.

如果使用这些与用例不匹配,我通常会使用 top 声明,这样我就可以避免您提到的问题。

回答by Putzi San

best practice here should be good programming style:

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

A program should be constructed in short functions, which will do one little task. Usually, if you're looping, you do something such special which should stand in an own function. In the end every function has his own scope, so that the duplicate-declaration-problem is away.

一个程序应该用简短的函数来构建,这将完成一项小任务。通常,如果你在循环,你会做一些特殊的事情,这些事情应该放在一个自己的函数中。最后,每个函数都有自己的作用域,这样重复声明的问题就消失了。

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