在回答之前,请先阅读整个问题。

我一直在看你不能在压力测验下做JavaScript,并提出了关于对数组中的值求和的问题。我编写了以下函数(最初没有console.log语句),并且在输入[[1,2,3],4,5]时表现不正常-返回10而不是15。最终,我弄清楚了解决它-在var前面加上var和求和。在Firefox的Scratchpad中进行调试时,我一直在执行此操作,在Firebug中查看控制台输出。

function arraySum(i) {

    // i will be an array, containing integers, strings and/or arrays like itself.
    // Sum all the integers you find, anywhere in the nest of arrays.

    n=0;
    sum=0;
    console.log(i.length)
    while(n<i.length){

        console.log("i["+n+"]="+i[n]);

         if(i[n].constructor==Array){
             console.log("array n="+n)
            sum+=arraySum(i[n]);
            console.log("out array n="+n)
        }
        else if(typeof(i[n])=="number"){
            console.log("number")
        sum+= i[n];

        }
        n++;
        console.log("sum="+sum+" n="+n)
    }
    return sum

}
console.log(arraySum([1,[1,2,3],2] ) );


输出是

start
Scratchpad/1 (line 9)
3
Scratchpad/1 (line 17)
i[0]=1
Scratchpad/1 (line 20)
number
Scratchpad/1 (line 28)
sum=1 n=1
Scratchpad/1 (line 33)
i[1]=1,2,3
Scratchpad/1 (line 20)
array n=1
Scratchpad/1 (line 23)
3
Scratchpad/1 (line 17)
i[0]=1
Scratchpad/1 (line 20)
number
Scratchpad/1 (line 28)
sum=1 n=1
Scratchpad/1 (line 33)
i[1]=2
Scratchpad/1 (line 20)
number
Scratchpad/1 (line 28)
sum=3 n=2
Scratchpad/1 (line 33)
i[2]=3
Scratchpad/1 (line 20)
number
Scratchpad/1 (line 28)
sum=6 n=3
Scratchpad/1 (line 33)
out array n=3
Scratchpad/1 (line 25)
sum=7 n=4
Scratchpad/1 (line 33)
7


所以最终我发现,当递归调用该函数时,外部函数的n变量将重置为0并修改为3,所以当它退出时,而不是再循环一次(如果n为2)离开功能。这一切都是有意义的,直到您考虑了sum变量,该变量应处于相同的条件下:在递归调用中重置为0,然后在退出函数的递归调用时最终为6,

所以我的问题是这样的:

为什么我得到7而不是6?

最佳答案

ECMA-262(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources)定义了:


  11.13.2复合分配(op =)
  
  生产AssignmentExpression:LeftHandSideExpression AssignmentOperator AssignmentExpression,其中AssignmentOperator为@ =,@表示上述指示的运算符之一,按以下方式评估:
  
  
  令lref为评估LeftHandSideExpression的结果。
  令lval为GetValue(lref)。
  令rref为评估AssignmentExpression的结果。
  令rval为GetValue(rref)。
  令r为将运算符@应用于lval和rval的结果。
  如果满足以下所有条件,则引发SyntaxError异常:
  
  Type(lref)是Reference为true
  IsStrictReference(lref)为true
  Type(GetBase(lref))是环境记录
  GetReferencedName(lref)是“ eval”或“ arguments”
  
  调用PutValue(lref,r)。
  返回r。
  


在您的示例中,代码sum += arraySum(i[n])的含义是:


获取总和变量
获取sum的值并将其临时存储在lval内部变量中
引用函数调用arraySum(i [n])
获取函数调用的结果并将其存储在rval内部变量中
添加lvalrval
确保没有问题
将结果存储在您的总和中
也返回此结果


您的递归有问题,因为第二次调用arraySum时,您覆盖了全局变量nsum。覆盖sum没问题,因为您使用了+=运算符,但是在将n倒退到4后结束了对arraySum的第一次调用。

09-20 11:54