javascript 参数范围问题和函数 return

javascript argument scoping issue and function return

我的函数范围界定有 2 个小问题:

  1. 首先是自由论证的范围界定。一切顺利,直到它到达主 'else' 块,当变量在 return 进入前一个递归时被重置。将自由作为一个全局变量解决了这个问题,但这不是应该做的...

  2. 函数中的最后一个 return 未定义。即使我可以轻松 console.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 用于 neighbors 函数。如果您需要任何其他信息,请告诉我 :) 请指教。提前致谢!

编辑: 感谢 Jaromanda X,我通过以下方式修复了 return 值问题:

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
}

然而,自由范围问题仍然存在

您可以使用内部函数在闭包中捕获 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 被移出。您可能也想考虑移出其他变量,我不确定您是否需要在关闭后传递 boardvisitedgroup。我还猜测 visitedgroup 将不再需要作为外部函数的参数,它们可以像 liberties.

一样创建为变量

通过使用两个函数,我们为变量作用域引入了一个额外的层次,允许我们将变量从内部函数中推出,而不必一直到全局。