javascript - 如何使用递归更新局部范围的变量
问题描述
如果这是一个过于笼统的问题,请原谅我,但是当我需要开发递归算法来更新每个递归调用的一些值时,我似乎经常遇到这个问题。请看下面这个例子:
我想制作一个递归算法来累积给定配置文件的年龄以及该配置文件中存在的所有孩子和孩子的孩子等。
型材结构:
const profile = {
name: 'peter',
age: 56,
kids: [{
name: 'jill',
age: 23,
kids: [{
name: 'jeter',
age: 1
}, {
name: 'bill',
age: 2
}]
}]
}
如果我在函数范围之外声明一个变量并更新它的工作原理。像这样:
let totalage = 0
function getAge(profile) {
totalage = profile.age + totalage
if(!profile.kids) return
for(const kid of profile.kids) {
getAge(kid)
}
}
getAge( profile)
console.log(totalage)
按照这个逻辑,为了使函数更可重用,我想创建一个 shell 函数来设置年龄变量,这样就不必在任何时候全局声明我想要获取所有年龄,但是这个解决方案返回 0,原始年龄值:
function getAges(profile) {
let age = 0
recurs( profile, age)
return age
}
function recurs(profile, age) {
age = profile.age + age
if(!profile.kids) return
for(const kid of profile.kids) {
recurs(kid, age)
}
}
console.log(getAges(profile))
知道有什么问题吗?
解决方案
我想创建一个设置 age 变量的 shell 函数,这样当我想获得所有年龄时就不必全局声明它。知道有什么问题吗?
您需要在recurse
内部声明函数getAges
,以便它可以age
通过闭包访问变量。请注意,JS 对于函数调用只有按值传递语义,因此当您将变量 ( age
) 作为参数传递给函数时,分配给参数 ( age
) 只会更新函数内部的局部变量。
function getAges(profile) {
let age = 0
function recurs(profile, age) {
age += profile.age
if (!profile.kids) return
for (const kid of profile.kids)
recurse(kid)
}
recurse(profile)
return age
}
console.log(getAges(profile))
但正如其他答案所提到的,递归利用返回值要好得多,就像在@Nick 或@ippi 的片段中一样。
推荐阅读
- python - 在 Python 中将任何用户输入转换为 int
- node.js - 无法升级 Expo CLI
- android - 可通过下载观察到的 RxJava 链
- javascript - 如何在 GreaseMonkey 中调用`getEventListeners`
- ios - UITableViewController 返回到单元格中的下一个文本字段
- r - 从 R 中的数据框/小标题中采样分组行
- python - 如何制作对象属性列表并从列表中更改?
- android - 在手机之间交换本地文件的方法
- python-3.x - 用于传入变量的 SQLAlchemy .execute() 语法
- xcode - UserDefaults 的 Xcode XCTestCase 设置值