
本文解析了 JavaScript 质数查找函数中因错误修改循环变量 i 和缺失素性判定机制,导致将合数(如 33、35)误判为质数的根本原因,并提供结构清晰、高效可靠的修正实现。
本文解析了 javascript 质数查找函数中因错误修改循环变量 `i` 和缺失素性判定机制,导致将合数(如 33、35)误判为质数的根本原因,并提供结构清晰、高效可靠的修正实现。
原始代码存在两个关键逻辑缺陷:
- 在内层循环中主动递增 i(i++),破坏了外层 for 循环对 i 的自然控制,导致跳过待检测数字(如跳过 34 直接检查 35),甚至将被排除的合数 i 的后继值(如 33 → 34)错误地写入结果;
- 缺乏素性判定机制:未区分“找到因子”(非质数)与“遍历完所有可能因子仍未找到”(质数)两种情况,而是无条件将每次循环结束时的 i 值加入数组。
正确做法是引入布尔标志 isPrime,在内层循环前初始化为 true,一旦发现能整除 i 的因子(i % j === 0),立即将其置为 false 并 break 退出;循环结束后,仅当 isPrime 仍为 true 时才将 i 推入结果数组。
此外,Math.floor(Math.sqrt(i)) 在边界情况下(如 i = 4,√4 = 2)虽无误,但为语义清晰与兼容性,推荐使用 Math.ceil(Math.sqrt(i)) 或更稳妥的 Math.floor(Math.sqrt(i)) + 1;同时,使用 Array.prototype.push() 替代手动索引赋值,提升可读性与健壮性。
以下是修复后的完整实现:
立即学习“Java免费学习笔记(深入)”;
function primeFinder(n) {
const primes = [];
for (let i = 2; i <= n; i++) {
const root = Math.floor(Math.sqrt(i));
let isPrime = true;
for (let j = 2; j <= root; j++) {
if (i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(i);
}
}
return primes;
}
console.log(primeFinder(35));
// 输出: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]✅ 验证结果:33(=3×11)和 35(=5×7)不再出现在输出中,所有返回值均为严格意义上的质数。
⚠️ 注意事项:该算法时间复杂度为 O(n√n),适用于中小规模输入(如 n


















