Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么return不是递归函数中的finishing函数_Javascript_Recursion_P5.js - Fatal编程技术网

Javascript 为什么return不是递归函数中的finishing函数

Javascript 为什么return不是递归函数中的finishing函数,javascript,recursion,p5.js,Javascript,Recursion,P5.js,我有这支笔在codepe中,我有一个递归函数名为“getRandomPos”,该函数通过从另一个数组中随机选择的值填充一个名为“randomPos”的数组,该数组作为名为“dimensionArray”的参数传递 如果新数组的长度大于参数“amount”,则应返回新数组 单击画布时,该函数将运行 如果您打开了devtools,因为第17行有一个调试器,您可以使用chrome中devtools中的“下一次函数调用的步骤”按钮来完成函数步骤,您将看到“randomPos”数组的长度大于“amount

我有这支笔在codepe中,我有一个递归函数名为“getRandomPos”,该函数通过从另一个数组中随机选择的值填充一个名为“randomPos”的数组,该数组作为名为“dimensionArray”的参数传递

如果新数组的长度大于参数“amount”,则应返回新数组

单击画布时,该函数将运行

如果您打开了devtools,因为第17行有一个调试器,您可以使用chrome中devtools中的“下一次函数调用的步骤”按钮来完成函数步骤,您将看到“randomPos”数组的长度大于“amount”参数之后,它应该返回随机POS

但事实并非如此

它从第30行到第31行循环三次三次

我不明白这一点,不应该返回,只是停止函数并返回randomPos

这是代码,这是代码笔上的笔:

让getRandomFromArray=(项)=>{
let item=items[Math.floor(Math.random()*items.length)]
退货项目
}
设行数=20,
cols=50,
randomXUnits=[],
randomYUnits=[],
画布宽度=500,
画布高度=200,
gridXDiv=(画布宽度/cols),
gridYDiv=(画布高度/行),
randomPos=[]
让getRandomPos=(金额,维度数组)=>{
调试器;
设randomUnit=getRandomFromArray(dimensionArray)
if(随机位置长度<数量){
if(随机位置包括(随机单位)){
getRandomPos(数量、维度数组)
}否则{
随机位置推送(随机单元)
getRandomPos(数量、维度数组)
}
} 
返回随机位置
}
让drawDivisions=(randomPosArray,dimension)=>{
randomPosArray.forEach(p=>{
填充(255)
noStroke()
如果(尺寸===画布宽度){
矩形(p,0,gridXDiv,画布高度)
}否则{
矩形(0,p,画布宽度,gridXDiv)
} 
})
}
函数设置(){
createCanvas(画布宽度、画布高度)
背景(0)
对于(设i=gridXDiv;i
这是因为您正在使用递归,并且
getRandomPos
没有完成递归调用,调用堆栈如下所示:

  • 通过单击鼠标,使用参数3和randomXUnits调用
    getRandomPos
    • 0
      getRandomPos
      测试randomPos是否小于金额,false
      • 1
        getRandomPos
        测试randomPos是否小于金额,false
        • 2
          getRandomPos
          测试randomPos是否小于金额,false
          • 3
            getRandomPos
            测试randomPos是否小于金额,true然后
          • 返回3
        • 返回2
      • 返回1
    • 返回0

返回
randomPos
实际上会停止该函数的执行,因此会发生其他事情。我怀疑您看到了所有其他递归。还要注意的是,您并不是在每个可能的分支中都从getRandomPos返回。如果
randomPos.length
,则不返回任何内容。通过再次调用
getRandomPos
进行递归,但您永远不会返回它提供给您的内容。一个全局可变变量,非常可疑,本质上是buggy@Carcigenicate如果
randomPos.length
我不会返回,因为如果
randomPos
length小于
amount
,它必须继续递归。。。如果
randompos
长度不小于
amount
,则它将返回。。。因为我希望
randomPos
的长度与
amount
@GiorgioMartini的长度相同,但如果不返回递归调用的结果,则该调用创建的任何结果都将丢失。当然,除非你改变一个全局变量,但是递归+可变全局变量=其他人提到的粗略业务。谢谢,那么我如何让getRandomPos完成递归调用呢?如果在主函数和If语句上添加返回值不起作用,那么这并没有错,实际上是递归的自然行为,正如@Carcigenicate所说:查找递归阶乘函数的实现,它具有相同的行为。如果您想在“return”语句中完成对函数的调用,那么您必须更改代码以使用类似for或while的循环。我已经按照您的建议更改为while循环,但我确信一定有一种方法可以通过递归实现。。我想学习递归,我听说所有可以用循环完成的事情都可以用递归完成。。。我将问另外一个问题,关于如何用递归实现我想要的。。因为这个问题真的是关于为什么返回没有完成。。。谢谢
let getRandomFromArray = (items) => {
  let item = items[Math.floor(Math.random()*items.length)]
  return item
}

let rows = 20,
    cols = 50,
    randomXUnits = [],
    randomYUnits = [],
    canvasWidth = 500,
    canvasHeight = 200,
    gridXDiv = (canvasWidth/cols),
    gridYDiv = (canvasHeight/rows),
    randomPos = []


let getRandomPos = (amount, dimensionArray) => {
  debugger;
  let randomUnit = getRandomFromArray(dimensionArray)

    if(randomPos.length < amount){
      if(randomPos.includes(randomUnit)){
        getRandomPos(amount, dimensionArray) 
      }else{
        randomPos.push(randomUnit)
        getRandomPos(amount, dimensionArray) 
      }
    } 
  return randomPos  
}

let drawDivisions = (randomPosArray, dimension) => {
    randomPosArray.forEach( p => {
    fill(255)
    noStroke() 
    if(dimension === canvasWidth){
       rect(p,0,gridXDiv, canvasHeight)    
    }else{
       rect(0,p,canvasWidth, gridXDiv)   
     } 
  })
}

function setup(){
  createCanvas(canvasWidth,canvasHeight)
  background(0)
  for (let i = gridXDiv; i < width-(gridXDiv-1); i+= gridXDiv) {
      randomXUnits.push(i)
    for (let j = gridYDiv; j < height-(gridYDiv-1); j+= gridYDiv) {
      if (randomYUnits.length < 20) {
        randomYUnits.push(j)
      }
    stroke(255)
    point(i,j)
    }
  }
}

function draw(){

}

function mouseClicked() {
  background(0)

  randomPos = []
  let usedPositionsInX = getRandomPos(3, randomXUnits)
  drawDivisions(usedPositionsInX,canvasHeight)


  let usedPositionsInY = getRandomPos(3, randomYUnits)
  drawDivisions(usedPositionsInY,canvasWidth)

}