我试图理解Javascript和递归编程的行为。
Npw,我是个初学者,所以我需要了解为什么我已经被声明为错误,而当我还没有被声明为错误
考虑这段代码,我试图了解它如何执行。
let company = { // the same object, compressed for brevity
sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }],
development: {
sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
internals: [{name: 'Jack', salary: 1300}]
}
};
// The function to do the job
function sumSalaries(department) {
if (Array.isArray(department)) {
return department.reduce((prev, current) => prev + current.salary, 0);
} else { // case (2)
let sum = 0;
for (let subdep of Object.values(department)) {
sum = sum + sumSalaries(subdep);
}
return sum;
}
}
console.log(sumSalaries(company));// 6700
中断上述代码的执行(如果我理解错了,那就对了)
从本质上讲,它不是数组,因为company是上面的对象。
let subdep of Object.values(department
的第一次迭代中,我们将得到
[{…}, {…}] inside which we have following object {name: "John", salary: 1000}
sumSalaries(subdep);
的内容现在,由于我们正在传递数组,它将进入以下函数
if(Array.isArray(department)){ return department.reduce((prev,current)=> prev + current.salary,0); }
在我们之前的文章中,我们传递0并将其与current.salary相加。
0 + 1000
,然后将添加1000 + 600
sum
将为0 + 1600 if (Array.isArray(department)) {
并转到else
问题+问题 当我完成十三点的时候,我意识到我们的第二个声明让sum = 0
所以,两件事
因为我们有let sum = 0
,所以应该没有错误说明 let sum 已经存在
无论哪种方式,我们都执行sum = 0,这是否意味着sum数组中的先前值(1600
)消失了(换句话说,重置为零?
答案 0 :(得分:4)
let
是块范围的,这意味着可以在多个块中包含多个声明。每次您呼叫sumSalaries()
时,sum
将被重置为零。它不需要记住以前的调用,因为如果找到此调用,它将返回总和,随着递归展开,该调用将添加到调用递归函数的父级中。
使用策略性放置的console.log()
调用或使用调试器来观察递归可能是有益的。例如,您可以观看总计为:
let company = { // the same object, compressed for brevity
sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }],
development: {
sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
internals: [{name: 'Jack', salary: 1300}]
}
};
// The function to do the job
function sumSalaries(department) {
if (Array.isArray(department)) {
return department.reduce((prev, current) => prev + current.salary, 0);
} else { // case (2)
console.log("starting new object")
let sum = 0;
for (let subdep of Object.values(department)) {
let subsum = sumSalaries(subdep)
console.log("subsum = ", subsum)
sum = sum + subsum;
}
console.log("current sum:", sum)
return sum;
}
}
console.log(sumSalaries(company));// 6700
答案 1 :(得分:1)
每次调用一个函数时,它都会创建一个新的空间(通常称为“作用域”或“堆栈框架”)以容纳在其中声明的所有变量。
仅当您在同一空间两次声明同一变量
时,才会显示变量已声明的错误。因为在第一次调用sumSalaries和第二次(递归)调用中创建的'sum'变量位于不同的空格,所以不会出现错误。
答案 2 :(得分:0)
在javascript中,函数本质上是一个作用域。
相同函数的递归调用也将是独立作用域。在上一个递归函数调用中声明的变量sum
与在下一个递归函数调用中声明的变量不同。
您只会得到
Identifier has already been declared
如果在同一范围内两次声明变量。