我的功能范围内有2个小问题:
首先是对自由论证的范围。当返回到先前的递归时变量被重置时,一切正常,直到它到达主“else”块。将自由作为一个全局变量来解决问题,但这不是应该如何做的......
函数中的最后一个返回给出了undefined。即使我可以轻松地控制.log这些变量(它们在所有情况下都是正确的,除了自由,如果不是全局的话)。我在这里看不到任何异步行为,它让我感到困惑。它是如何工作的。
function getGroup(position, board, visited = [], group = [], liberties = 0) {
let pointNotVisited = visited.reduce((acc, cur) => (cur.x !== position.x || cur.y !== position.y) && acc, true)
if (pointNotVisited) {
let neighbours = getNeighbours(position, board)
group.push(position)
visited.push(position)
let unvisitedNeighbours = neighbours.reduce((acc, cur) => {
let neighbourVisited = visited.filter(el => (el.x === cur.x && el.y === cur.y))
if (neighbourVisited.length > 0) {
return acc
} else {
return acc.concat(cur)
}
}, [])
unvisitedNeighbours.forEach(stone => {
if (stone.color == 'empty') {
liberties++
visited.push(stone)
} else if (stone.color != position.color) {
visited.push(stone)
}
return getGroup(stone, board, visited, group)
})
} else {
return {
'group': group,
'liberties': liberties
}
}
}
注意:position的格式为:{x:1,y:3,color:“white”},board用于邻居函数。如果您需要任何其他信息,请告诉我:) 请指教。提前谢谢!
编辑: 感谢Jaromanda X我修复了返回值问题:
unvisitedNeighbours.forEach(stone => {
if (stone.color == 'empty') {
liberties++
visited.push(stone)
// console.log('liberties after increment', liberties)
} else if (stone.color != position.color) {
visited.push(stone)
}
// console.log('liberties before recursion', liberties)
getGroup(stone, board, visited, group, liberties)
})
return {
"group": group,
"liberties": liberties
}
然而,自由范围问题仍然存在
答案 0 :(得分:1)
您可以使用内部函数捕获闭包中的liberties
变量,而不是尝试传递它。它看起来像这样:
function getGroup(position, board, visited = [], group = []) {
var liberties = 0
return myInnerFn(position, board, visited, group)
function myInnerFn(position, board, visited, group) {
// ... does grouping logic, recursively calling itself ...
}
}
此处myInnerFn
应该执行getGroups
中的所有逻辑,只有liberties
已移出。您可能还想考虑移出其他变量,我不确定您是否需要在关闭后传递board
,visited
或group
。我也猜测将不再需要visited
和group
作为外部函数的参数,它们可以像liberties
一样创建为变量。
通过使用两个函数,我们为变量作用域引入了一个额外的级别,允许我们将变量从内部函数中推出,而不必一直到全局。