JS 为什么整数变量被重置为初始值而数组变量却没有?
JS Why is the integer variable being reset to initial value but the array variable not?
给定一个 matrix/graph/multidimensional 数组的输入(不太确定它们在编程中是否具有唯一定义),下面的函数应该输出最大岛的大小。土地用 1 表示,水用 0 表示,两个有土地的区域只有在水平或垂直(不是对角线)相邻时才相连。
下面的算法有效,但只有当我将所有岛屿保存在一个数组中时,"islands" 变量然后 return 保存的最大值。
最初,我试图仅跟踪 "biggest" 变量的最大值的大小。但是,由于某种原因,它一直被重置为初始值 0。
为什么会这样?我特别困惑为什么这可能发生在 "biggest" 变量而不是 "islands" 变量上,因为两者似乎具有完全相同的范围。
const bigIsland = matrix => {
let biggest = 0
let islands = []
let visited = matrix.map(row => row.map(node => false))
for(let y=0; y<matrix.length; y++){
for(let x=0; x<matrix[y].length; x++){
if (visited[y][x]) continue
checkIsland(matrix, visited, y, x, islands, biggest)
}
}
return Math.max(...islands)
}
const checkIsland = (matrix, visited, y, x, islands, biggest) => {
console.log("biggestStart", biggest)
console.log("islandsStart", islands)
let currIsland = 0
let nodesToCheck = [[y,x]]
while(nodesToCheck.length){
const [y, x] = nodesToCheck.pop()
if (visited[y][x]) continue
visited[y][x] = true
if (matrix[y][x]===0) continue
currIsland++
console.log("currIsland", currIsland)
getValidNeighbors(matrix, visited, y, x, nodesToCheck)
}
if (currIsland > biggest) biggest = currIsland
if (currIsland > 0) islands.push(currIsland)
console.log("biggest", biggest)
console.log("islands", islands)
}
const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
if(y>0) nodesToCheck.push([y-1, x])
if(y<matrix.length-1) nodesToCheck.push([y+1, x])
if(x>0) nodesToCheck.push([y, x-1])
if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}
bigIsland([ [1, 0, 1],
[1, 0, 1],
[1, 0, 0] ])
函数bigIsland
中的变量biggest
独立于checkIsland
中的变量biggest
。改变一个函数中的变量对另一个函数没有影响。数组是不同的,因为当您传递数组时,您会在变量中获得对同一数组的引用。考虑:
function one() {
let variable = 0;
console.log("variable in on before calling two ", variable)
two(variable)
console.log("variable in on after calling two ", variable)
}
function two(variable) {
variable += 200
console.log("variable in two", variable)
}
one()
如果你想让两个函数都改变同一个变量,你可以把这个变量放在一个范围内,两者都可以看到:
let variable = 0
function one(){
console.log("variable in on before calling two ", variable)
two()
console.log("variable in on after calling two ", variable)
}
function two() {
variable += 200
console.log("variable in two", variable)
}
one()
或者您可以将其作为对象传递,这是一种非常标准的传递方式:
function one() {
let obj = {variable: 0}
console.log("variable in on before calling two ", obj.variable)
two(obj)
console.log("variable in on after calling two ", obj.variable)
}
function two(obj) {
// notice we are not reassigning the variable obj with obj = 200
// but changing the thing obj refers to
obj.variable += 200
console.log("variable in two", obj.variable)
}
one()
当您将原始变量传递给函数时(例如 biggest
传递给 checkIsland
),函数中的任何内容 都可以将原始引用更改为调用函数中的那个变量。为了在 bigIsland
中更改 biggest
,您需要明确 return 从 checkIsland
:
中找到的 biggest
const bigIsland = matrix => {
let biggest = 0
let islands = []
let visited = matrix.map(row => row.map(node => false))
for(let y=0; y<matrix.length; y++){
for(let x=0; x<matrix[y].length; x++){
if (visited[y][x]) continue
biggest = checkIsland(matrix, visited, y, x, islands, biggest)
}
}
return Math.max(...islands)
}
const checkIsland = (matrix, visited, y, x, islands, biggest) => {
console.log("biggestStart", biggest)
console.log("islandsStart", islands)
let currIsland = 0
let nodesToCheck = [[y,x]]
while(nodesToCheck.length){
const [y, x] = nodesToCheck.pop()
if (visited[y][x]) continue
visited[y][x] = true
if (matrix[y][x]===0) continue
currIsland++
console.log("currIsland", currIsland)
getValidNeighbors(matrix, visited, y, x, nodesToCheck)
}
if (currIsland > biggest) biggest = currIsland
if (currIsland > 0) islands.push(currIsland)
console.log("biggest", biggest)
console.log("islands", islands)
return biggest;
}
const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
if(y>0) nodesToCheck.push([y-1, x])
if(y<matrix.length-1) nodesToCheck.push([y+1, x])
if(x>0) nodesToCheck.push([y, x-1])
if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}
bigIsland([ [1, 0, 1],
[1, 0, 1],
[1, 0, 0] ])
另一方面,当您传递 islands
时,islands
是一个 数组 ,它是一个对象(非原始类型),所以当islands
在 checkIsland
内部发生变异,它的变化也将在其他任何地方可见。引用非基元的变量本质上是对对象在内存中的内存位置的引用 - 对象在传递时不会被复制,除非你明确地这样做。
给定一个 matrix/graph/multidimensional 数组的输入(不太确定它们在编程中是否具有唯一定义),下面的函数应该输出最大岛的大小。土地用 1 表示,水用 0 表示,两个有土地的区域只有在水平或垂直(不是对角线)相邻时才相连。
下面的算法有效,但只有当我将所有岛屿保存在一个数组中时,"islands" 变量然后 return 保存的最大值。
最初,我试图仅跟踪 "biggest" 变量的最大值的大小。但是,由于某种原因,它一直被重置为初始值 0。
为什么会这样?我特别困惑为什么这可能发生在 "biggest" 变量而不是 "islands" 变量上,因为两者似乎具有完全相同的范围。
const bigIsland = matrix => {
let biggest = 0
let islands = []
let visited = matrix.map(row => row.map(node => false))
for(let y=0; y<matrix.length; y++){
for(let x=0; x<matrix[y].length; x++){
if (visited[y][x]) continue
checkIsland(matrix, visited, y, x, islands, biggest)
}
}
return Math.max(...islands)
}
const checkIsland = (matrix, visited, y, x, islands, biggest) => {
console.log("biggestStart", biggest)
console.log("islandsStart", islands)
let currIsland = 0
let nodesToCheck = [[y,x]]
while(nodesToCheck.length){
const [y, x] = nodesToCheck.pop()
if (visited[y][x]) continue
visited[y][x] = true
if (matrix[y][x]===0) continue
currIsland++
console.log("currIsland", currIsland)
getValidNeighbors(matrix, visited, y, x, nodesToCheck)
}
if (currIsland > biggest) biggest = currIsland
if (currIsland > 0) islands.push(currIsland)
console.log("biggest", biggest)
console.log("islands", islands)
}
const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
if(y>0) nodesToCheck.push([y-1, x])
if(y<matrix.length-1) nodesToCheck.push([y+1, x])
if(x>0) nodesToCheck.push([y, x-1])
if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}
bigIsland([ [1, 0, 1],
[1, 0, 1],
[1, 0, 0] ])
函数bigIsland
中的变量biggest
独立于checkIsland
中的变量biggest
。改变一个函数中的变量对另一个函数没有影响。数组是不同的,因为当您传递数组时,您会在变量中获得对同一数组的引用。考虑:
function one() {
let variable = 0;
console.log("variable in on before calling two ", variable)
two(variable)
console.log("variable in on after calling two ", variable)
}
function two(variable) {
variable += 200
console.log("variable in two", variable)
}
one()
如果你想让两个函数都改变同一个变量,你可以把这个变量放在一个范围内,两者都可以看到:
let variable = 0
function one(){
console.log("variable in on before calling two ", variable)
two()
console.log("variable in on after calling two ", variable)
}
function two() {
variable += 200
console.log("variable in two", variable)
}
one()
或者您可以将其作为对象传递,这是一种非常标准的传递方式:
function one() {
let obj = {variable: 0}
console.log("variable in on before calling two ", obj.variable)
two(obj)
console.log("variable in on after calling two ", obj.variable)
}
function two(obj) {
// notice we are not reassigning the variable obj with obj = 200
// but changing the thing obj refers to
obj.variable += 200
console.log("variable in two", obj.variable)
}
one()
当您将原始变量传递给函数时(例如 biggest
传递给 checkIsland
),函数中的任何内容 都可以将原始引用更改为调用函数中的那个变量。为了在 bigIsland
中更改 biggest
,您需要明确 return 从 checkIsland
:
biggest
const bigIsland = matrix => {
let biggest = 0
let islands = []
let visited = matrix.map(row => row.map(node => false))
for(let y=0; y<matrix.length; y++){
for(let x=0; x<matrix[y].length; x++){
if (visited[y][x]) continue
biggest = checkIsland(matrix, visited, y, x, islands, biggest)
}
}
return Math.max(...islands)
}
const checkIsland = (matrix, visited, y, x, islands, biggest) => {
console.log("biggestStart", biggest)
console.log("islandsStart", islands)
let currIsland = 0
let nodesToCheck = [[y,x]]
while(nodesToCheck.length){
const [y, x] = nodesToCheck.pop()
if (visited[y][x]) continue
visited[y][x] = true
if (matrix[y][x]===0) continue
currIsland++
console.log("currIsland", currIsland)
getValidNeighbors(matrix, visited, y, x, nodesToCheck)
}
if (currIsland > biggest) biggest = currIsland
if (currIsland > 0) islands.push(currIsland)
console.log("biggest", biggest)
console.log("islands", islands)
return biggest;
}
const getValidNeighbors = (matrix, visited, y, x, nodesToCheck) => {
if(y>0) nodesToCheck.push([y-1, x])
if(y<matrix.length-1) nodesToCheck.push([y+1, x])
if(x>0) nodesToCheck.push([y, x-1])
if(x<matrix[y].length-1) nodesToCheck.push([y, x+1])
}
bigIsland([ [1, 0, 1],
[1, 0, 1],
[1, 0, 0] ])
另一方面,当您传递 islands
时,islands
是一个 数组 ,它是一个对象(非原始类型),所以当islands
在 checkIsland
内部发生变异,它的变化也将在其他任何地方可见。引用非基元的变量本质上是对对象在内存中的内存位置的引用 - 对象在传递时不会被复制,除非你明确地这样做。