Javascript—嵌套for循环索引的范围

Javascript—嵌套for循环索引的范围,javascript,nested-loops,Javascript,Nested Loops,我记得变量在Javascript中是函数作用域。但是,如果我在循环中重新定义局部变量,行为会如何呢。一个常见的用例是嵌套循环。 在下面的代码中,如果我将j更改为I,则外部for循环在一次迭代后终止,因为外部范围中的I的值与内部for循环的值相同。因为我使用了var,所以我希望(和其他语言类似)它在内部fo循环中被重新定义。这是否意味着在JS中,无法在函数范围内重新声明和使用局部变量 for (var i = 0, len = x.length; i < len; i++) {

我记得变量在Javascript中是函数作用域。但是,如果我在循环中重新定义局部变量,行为会如何呢。一个常见的用例是嵌套循环。 在下面的代码中,如果我将j更改为I,则外部for循环在一次迭代后终止,因为外部范围中的I的值与内部for循环的值相同。因为我使用了var,所以我希望(和其他语言类似)它在内部fo循环中被重新定义。这是否意味着在JS中,无法在函数范围内重新声明和使用局部变量

for (var i = 0, len = x.length; i < len; i++) {
            ...
            for (var j = 0, len = y.length; j < len; j++) {
                ...
            }
        }
for(变量i=0,len=x.length;i
每个
var
申报都将被放入当前范围的顶部,因此您的代码与:

   var i, j, len;
   for (i = 0, len = x.length; i < len; i++) {
        ...
        for (j = 0, len = y.length; j < len; j++) {
            ...
        }
    }
var i,j,len;
对于(i=0,len=x.length;i

选中此项:

正如您所说,JavaScript只有函数作用域。变量声明被提升到声明它们的作用域的顶部。您的示例解释如下:

var i, j, len; //Declarations are hoisted...
for (i = 0, len = x.length; i < len; i++) { //Assignments happen in place
    for (j = 0, len = y.length; j < len; j++) {

    }
}
var i,j,len//声明被悬挂。。。
对于(i=0,len=x.length;i
关于这一部分:

如果我将j更改为I,则外部for循环在一次迭代后终止

如果将
j
替换为
i
,则在第一次迭代内环后,
i
将为
y.length-1
,外环将继续或停止,具体取决于
x.length
y.length
之间的差异

如果您对内部工作原理的真实解释感兴趣,本手册将详细介绍。总之,每次控件进入新的执行上下文时,都会发生以下情况(发生的情况远不止这些,但这是其中的一部分):

对于代码中的每个VariableDeclaration和VariableDeclarationNoIn d,在 源文本顺序do

  • 设dn为d中的标识符
  • 让varalreadydecared成为调用env的HasBinding具体函数的结果 方法将dn作为参数传递
  • 如果varalreadydecared为false,则
    • 调用env的CreateMutableBinding具体方法,传递dn和 可配置绑定作为参数
    • 调用env的SetMutableBinding 将dn、undefined和strict作为参数传递的具体方法

这意味着,如果您在每个执行上下文中多次声明变量,它将被有效地忽略。

JS中没有块级范围

但是,如果非常有必要在代码中重新声明相同的变量名,可以执行以下操作:

function loopIt(arr, fn, scope) {
    for (var i = 0, len = arr.length; i < len; i++) {
        fn.call(scope || this, arr[i], i, arr);
    }
}
这将为我们提供以下结果:

Hey it's 'a'
Hello it's 'c' in 'a'
Hello it's 'd' in 'a'
Hey it's 'b'
Hello it's 'c' in 'b'
Hello it's 'd' in 'b'

JavaScript没有块级别的作用域,只有函数级别,所以这是否意味着在JS中,无法在函数范围内重新声明和使用局部变量。->是的,这意味着更多关于马特的事情,你没有从风险值列表中遗漏
len
?我本想自己加上它,但我怀疑自己,因为@James也漏掉了:P.@xdazz:他做了,在两个循环中使用
var
关键字(以及
I
j
:P)。
Hey it's 'a'
Hello it's 'c' in 'a'
Hello it's 'd' in 'a'
Hey it's 'b'
Hello it's 'c' in 'b'
Hello it's 'd' in 'b'