javascript 参数范围问题和函数 return
javascript argument scoping issue and function return
我的函数范围界定有 2 个小问题:
首先是自由论证的范围界定。一切顺利,直到它到达主 'else' 块,当变量在 return 进入前一个递归时被重置。将自由作为一个全局变量解决了这个问题,但这不是应该做的...
函数中的最后一个 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
被移出。您可能也想考虑移出其他变量,我不确定您是否需要在关闭后传递 board
、visited
或 group
。我还猜测 visited
和 group
将不再需要作为外部函数的参数,它们可以像 liberties
.
一样创建为变量
通过使用两个函数,我们为变量作用域引入了一个额外的层次,允许我们将变量从内部函数中推出,而不必一直到全局。
我的函数范围界定有 2 个小问题:
首先是自由论证的范围界定。一切顺利,直到它到达主 'else' 块,当变量在 return 进入前一个递归时被重置。将自由作为一个全局变量解决了这个问题,但这不是应该做的...
函数中的最后一个 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
被移出。您可能也想考虑移出其他变量,我不确定您是否需要在关闭后传递 board
、visited
或 group
。我还猜测 visited
和 group
将不再需要作为外部函数的参数,它们可以像 liberties
.
通过使用两个函数,我们为变量作用域引入了一个额外的层次,允许我们将变量从内部函数中推出,而不必一直到全局。