javascript参数范围问题和函数返回

时间:2017-09-09 12:09:24

标签: javascript recursion scoping

我的功能范围内有2个小问题:

  1. 首先是对自由论证的范围。当返回到先前的递归时变量被重置时,一切正常,直到它到达主“else”块。将自由作为一个全局变量来解决问题,但这不是应该如何做的......

  2. 函数中的最后一个返回给出了undefined。即使我可以轻松地控制.log这些变量(它们在所有情况下都是正确的,除了自由,如果不是全局的话)。我在这里看不到任何异步行为,它让我感到困惑。它是如何工作的。

  3. 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
    }

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

1 个答案:

答案 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已移出。您可能还想考虑移出其他变量,我不确定您是否需要在关闭后传递boardvisitedgroup。我也猜测将不再需要visitedgroup作为外部函数的参数,它们可以像liberties一样创建为变量。

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