递归实现largestPrime函数出现Maximum Call Stack溢出错误求助
问题排查与修复
核心问题:全局变量污染
你代码里的count变量都没有用const/let声明,直接写成count = (...) => {...},这会把count变成全局变量。当largestPrime里调用isPrime(currNum)()时,isPrime会把全局的count替换成自己内部的递归函数;等isPrime的递归执行完,回到largestPrime里执行return count(currNum+1)时,这个count已经不是largestPrime原本的递归函数了,而是isPrime返回的素数判断函数——这套逻辑根本无法触发largestPrime的终止条件,最终导致无限递归、栈溢出。
为什么单独调用isPrime没问题?
单独调用时,全局count只会被当前isPrime的内部函数覆盖,递归过程中调用的count都是同一个函数,能正常走到终止条件(currNum === number),所以不会出问题。但和largestPrime配合时,两个函数的count互相覆盖,直接打乱了原本的递归逻辑。
修复代码
把两个函数里的count都改成局部变量,用const声明,彻底避免全局污染:
const isPrime = (number) => { // 用const声明局部count,隔离作用域 const count = (currNum = 2) => { // 优化:遍历到平方根即可,不用到number,大幅提升效率 if (currNum * currNum > number) { return true; } if (number % currNum === 0) { return false; } else { return count(currNum + 1); } } return count; } const largestPrime = (number) => { let currLargest = 0; // 同样用const声明局部count const count = (currNum = 2) => { if (currNum > number) { return currLargest; } else { if (isPrime(currNum)()) { currLargest = currNum; } return count(currNum + 1); } } return count; }
额外优化建议
isPrime的终止条件改成currNum * currNum > number:如果一个数有因数,其中一个因数肯定小于等于它的平方根,这样能减少大量递归次数。largestPrime可以倒序遍历:从输入的number开始往前找,找到第一个素数就直接返回,不用遍历所有数,效率更高:
const largestPrime = (number) => { const count = (currNum) => { if (currNum < 2) { return 0; // 处理无素数的边界情况 } if (isPrime(currNum)()) { return currNum; } return count(currNum - 1); } return count(number); }
内容的提问来源于stack exchange,提问作者Henry Zhang
相关产品推荐
相关产品推荐

