我试图理解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
打破上面代码的执行(如果我理解这个错误,请更正)
最初它不是一个数组,因为公司是上面的一个对象。
let subdep of Object.values(department
的第一次迭代中,我们将得到[{…}, {…}] inside which we have following object {name: "John", salary: 1000}
sumSalaries(subdep);
的返回值0 + 1000
然后它将添加1000 + 600
sum
将为0 + 1600if (Array.isArray(department)) {
而是转而去else
问题+问题虽然,我正在完成十三点,但我意识到我们的第二个声明让sum = 0
所以,有两件事
let sum = 0
,所以不应该有一个错误,说让sum已经存在了1600
)消失了(换句话说,重置为零?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
每次调用函数时,它都会创建一个新空间(通常称为“范围”或“堆栈框架”)来保存在其中声明的所有变量。
只有在同一空间中声明两次相同的变量时,才会显示变量已声明的错误
因为在第一次调用sumSalaries和第二次(递归)调用时创建的“sum”变量位于不同的空格中,所以不会出现错误。
在javascript中,函数本质上是一个范围。
相同函数的递归调用也将是独立的范围。在前一个递归函数调用中声明的变量sum
与在下一个函数调用中声明的变量不同。
你只会得到
Identifier has already been declared
如果在同一范围内声明变量两次。