请在回答之前阅读完整的问题。
我看着你在压力测验下不能做JavaScript并且得到了关于在数组中求和值的问题。我编写了以下函数(最初没有console.log语句),并且输入[[1,2,3],4,5]的行为不应该如此 - 返回10而不是15。最后我想出了如何修复它 - 在n和sum之前添加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?
答案 0 :(得分:2)
尝试在调试器中执行它。我试着精确而不是一步一步:
sum += arraySum(i[n]);
等效:sum = sum + arraySum(i[n]);
此时,sum = 1,需要确定arraySum
的值。n
和sum
已重置。n
未从上一次调用中重置,并指向超出数组末尾的位置。因此返回值7。要使代码按预期工作,必需使用var
,并且您错误地将以下内容括起来:
else if(typeof (i[n]=="number") )因此
typeof
适用于i[n]=="number"
,这不是您想要的(始终为boolean
!)
此外,我建议a
作为输入数组,i
作为迭代器,n
作为长度(n = a.length
)。
答案 1 :(得分:1)
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是将operator @应用于lval和rval的结果。
- 如果满足以下条件,则抛出SyntaxError异常:
- Type(lref)是Reference is true
- IsStrictReference(lref)为真
- 类型(GetBase(lref))是环境记录
- GetReferencedName(lref)是“eval”或“arguments”
- 调用PutValue(lref,r)。
- 返回r。
醇>
代码sum += arraySum(i[n])
的示例中的含义是:
lval
内部变量rval
内部变量lval
和rval
你的递归问题,因为当你第二次调用arraySum时,你覆盖了全局变量n
和sum
。覆盖sum
没问题,因为您使用了+=
运算符,但是在将n回放到4之后,您终止了对arraySum的第一次调用。