javascript 在多个 for 循环中使用相同的变量名是不好的做法吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15783144/
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-27 02:05:18  来源:igfitidea点击:

Is it bad practice to use the same variable name in multiple for-loops?

javascriptfor-loopjslintjshint

提问by TimG

I was just linting some JavaScript code using JSHint. In the code I have two for-loops both used like this:

我只是使用 JSHint 整理一些 JavaScript 代码。在代码中,我有两个 for 循环,它们都像这样使用:

for (var i = 0; i < somevalue; i++) { ... }

So both for-loops use the var i for iteration.

所以两个 for 循环都使用 var i 进行迭代。

Now JSHint shows me an error for the second for-loop: "'i' is already defined". I can't say that this isn't true (because it obviously is) but I always thought this wouldn't matter as the var i is only used in that specific place.

现在 JSHint 向我显示了第二个 for 循环的错误:“'i' 已经定义”。我不能说这不是真的(因为它显然是)但我一直认为这无关紧要,因为 var i 只在那个特定的地方使用。

Is it bad practice to use for-loops this way? Should I use a different variable for each for-loop in my code like

以这种方式使用 for 循环是不好的做法吗?我是否应该为代码中的每个 for 循环使用不同的变量,例如

//for-loop 1
for (var i = 0; ...; i++) { ... }

//for-loop 2
for (var j = 0; ...; j++) { ... }

Or is this on e of the errors I can ignore (because it doesn't break my code, it still does what it is supposed to do)?

或者这是我可以忽略的错误之一(因为它不会破坏我的代码,它仍然可以做它应该做的事情)?

JSLint btw. stops validating at the first for loop because I don't define var i at the top of the function (that's why I switched to JSHint in the first place). So according to the example in this question: Should I use JSLint or JSHint JavaScript validation?– I should use for-loops like this anyway to confirm JSLint:

JSLint 顺便说一句。在第一个 for 循环时停止验证,因为我没有在函数顶部定义 var i (这就是我首先切换到 JSHint 的原因)。所以根据这个问题中的例子:我应该使用 JSLint 还是 JSHint JavaScript 验证?– 无论如何,我应该使用这样的 for 循环来确认 JSLint:

...
var i;
...
//for-loop 1
for (i = 0; ...; i++) { ... }
...
//for-loop 2
for (i = 0; ...; i++) { ... }

This also looks good to me, because this way I should avoid both errors in JSLint and JSHint. But what I am uncertain about is if I should use a different variable for each for-loop like this:

这对我来说也很好,因为这样我应该避免 JSLint 和 JSHint 中的两个错误。但我不确定的是,我是否应该为每个 for 循环使用不同的变量,如下所示:

...
var i, j;
...
//for-loop 1
for (i = 0; ...; i++) { ... }
//for-loop 2
for (j = 0; ...; j++) { ... }

So is there a best practice for this or could I just go with any of the codes above, meaning I choose "my" best practice?

那么是否有最佳实践,或者我可以使用上面的任何代码,这意味着我选择“我的”最佳实践吗?

采纳答案by James Allardice

Since variable declarations are hoisted to the top of the scope in which they appear the interpreter will effectively interpret both versions in the same way. For that reason, JSHint and JSLint suggest moving the declarations out of the loop initialiser.

由于变量声明被提升到它们出现的范围的顶部,解释器将以相同的方式有效地解释两个版本。出于这个原因,JSHint 和 JSLint 建议将声明移出循环初始化程序。

The following code...

下面的代码...

for (var i = 0; i < 10; i++) {}
for (var i = 5; i < 15; i++) {}

... is effectively interpreted as this:

...被有效地解释为:

var i;
for (i = 0; i < 10; i++) {}
for (i = 5; i < 15; i++) {}

Notice that there is really only one declaration of i, and multiple assignments to it - you can't really "redeclare" a variable in the same scope.

请注意,实际上只有一个 声明i,并对其进行了多次赋值——您无法真正“重新声明”同一范围内的变量。

To actually answer your question...

要真正回答您的问题...

is there a best practice for this or could I just go with any of the codes above?

是否有最佳实践,或者我可以使用上面的任何代码吗?

There are varying opinions on how best to handle this. Personally, I agree with JSLint and think the code is clearer when you declare all variables together at the top of each scope. Since that's how the code will be interpreted, why not write code that looks as it behaves?

关于如何最好地处理这个问题,有不同的意见。就个人而言,我同意 JSLint 并认为当您在每个范围的顶部一起声明所有变量时,代码会更清晰。既然这就是代码的解释方式,为什么不编写看起来像它的行为的代码呢?

But, as you've observed, the code will work regardless of the approach taken so it's a style/convention choice, and you can use whichever form you feel most comfortable with.

但是,正如您所观察到的,无论采用何种方法,代码都可以工作,因此它是一种风格/约定选择,您可以使用您觉得最舒服的任何形式。

回答by Jashwant

Variables in javascript are function scoped (not block scoped).

javascript 中的变量是函数作用域的(不是块作用域的)。

When you define var iin a loop, it remains there in loop and also in the function having that loop.

当您var i在循环中定义时,它会保留在循环中以及具有该循环的函数中。

See below,

见下文,

function myfun() {
    //for-loop 1
    for (var i = 0; ...; i++) { ... }

    // i is already defined, its scope is visible outside of the loop1.
    // so you should do something like this in second loop.

    for (i = 0; ...; j++) { ... }

    // But doing such will be inappropriate, as you will need to remember
    // if `i` has been defined already or not. If not, the `i` would be global variable.
}

回答by serv-inc

It has been mentioned only in the comment by @TSCrowder: If your environment supports it (Firefox, Node.js), in ES6 you can use letdeclaration

仅在@TSCrowder 的评论中提到:如果您的环境支持它(Firefox、Node.js),则在 ES6 中您可以使用let声明

//for-loop 1
for (let i = 0; ...; i++) { ... }

//for-loop 2
for (let i = 0; ...; i++) { ... }

which limits the scope to within the for-loop. Bonus: JSHint stops complaining.

将范围限制在 for-loop 内。奖励:JSHint 停止抱怨。

回答by AlexMorley-Finch

I know this question has been answered, but if you want super for loops, write them like this:

我知道这个问题已经回答了,但是如果你想要超级循环,可以这样写:

var names = ['alex','john','paul','nemo'],
    name = '',
    idx = 0,
    len = names.length;

for(;idx<len;++idx)
{
    name = names[idx];
    // do processing...
}

A couple of things going on here...

这里发生了一些事情......

  1. The array length is being stored in len. This stops JS evaluating names.lengthevery iteration

  2. The idxincrement is a PRE-INCREMENT (e.g. ++idx NOT idx++). Pre-increments are natively faster than Post-increments.

  3. The storing of a reference to name. This is optional but recommended if you'll be using the namevariable a lot. Every call to names[idx]requires finding the index in the array. Whether this search be a linear search, tree search or hash table, the find is still happening. So store a reference in another variable to reduce lookups.

  1. 数组长度存储在len. 这将停止 JS 评估names.length每次迭代

  2. idx增量是一个PRE-增量(例如++ IDX NOT IDX ++)。Pre-increments 本身比 Post-increments 快。

  3. 存储对 的引用name。这是可选的,但如果您将name大量使用该变量,则建议使用。每次调用都names[idx]需要在数组中找到索引。无论此搜索是线性搜索、树搜索还是哈希表,查找仍在发生。因此,将引用存储在另一个变量中以减少查找。

Finally, this is just my personal preference, and I have no proof or any performance benefits. However I always like initialising variables to the type they're going to be e.g. name = '',.

最后,这只是我个人的喜好,我没有证据或任何性能优势。但是我总是喜欢将变量初始化为它们将要成为的类型,例如name = '',

回答by Corneliu

The reason JSHint shows the error is because in JS variable scope is function and variable declarations are hoisted to the top of the function.

JSHint 显示错误的原因是因为在 JS 变量范围内是函数,并且变量声明被提升到函数的顶部。

In Firefox you can use letkeyword to define block scope, but is not currently supported by other browsers.

在 Firefox 中,您可以使用let关键字来定义块范围,但目前其他浏览器不支持。

The letkeyword is included ECMAScript 6 specification.

let关键字包含在 ECMAScript 6 规范中。

回答by Nikolay Kostov

The best practice is to reduce the scope of variables, so the best way to declare iteration variable for the loops is

最佳实践是减少变量的范围,因此为循环声明迭代变量的最佳方法是

//for-loop 1
for (var i = 0; ...; i++) { ... }

//for-loop 2
for (var j = 0; ...; j++) { ... }

I know the scope of the variables declared with varbut I am taking about code readability here.

我知道用 with 声明的变量的范围,var但我在这里考虑的是代码可读性。