- 今天在练习一个分解质因数的算法
// 判断这个因数是否是质因数
function isPrime (num) {
let f = true
for (let i = 2; i < Math.floor(num / 2); i++) {
if (num % i === 0) {
f = false
break;
}
}
return f;
}
let n = 180
// 存放质因数的数组
let arr = []
// 分解质因数
function divide (num) {
for (let i = 2; i <= Math.floor(num / 2); i++) {
// 如果是质因数就保存下来
if (num % i === 0 && isPrime(i)) {
arr.push(i)
num = num / i;
i--
continue
}
}
}
divide(n)
console.log(arr);
是不是乍一看感觉能得到质因数。那么恭喜你,你成功踩到坑里了。这个程序的输出结果是这个样子滴

质因数
是不是发现少了点什么,没错,就是少了最后一个质因数5。笔者多次尝试发现总是少最后一个质因数,反复阅读程序认为逻辑没有错误。但作为一个被JS作用域折磨已久的菜鸡,总觉得是for循环的判断条件那出问题了。于是写了个demo测试了下
let arr = [1, 2, 3, 4]
for (let i = 0; i < arr.length; i++) {
console.log(i)
arr.length--
}
正常情况下你是不是认为应该输出0,1,2,3。但结果却是这个样子的

动态改变for循环的判断条件
我们本来以为for循环应该循环arr.length也就是4次,但结果却是循环了两次,这就意味着for循环里的
( ; ; )判断条件是动态变化的(我之前一直以为是不变的233333)。具体为什么变化我觉得可能和JS特有的作用域链有关吧,笔者也没有研究过底层,望知道底层原理的大佬可以分享下。最后放一个改进的分解质因数的程序
// 判断这个因数是否是质因数
function isPrime (num) {
let f = true
for (let i = 2; i < Math.floor(num / 2); i++) {
if (num % i === 0) {
f = false
break;
}
}
return f;
}
let n = 180
// 存放质因数的数组
let arr = []
// 质因数的最大判断条件
let base = Math.floor(n / 2)
// 分解质因数
function divide (num) {
for (let i = 2; i < base; i++) {
// 如果是质因数就保存下来
if (num % i === 0 && isPrime(i)) {
arr.push(i)
num = num / i;
i--
continue
}
}
}
divide(n)
console.log(arr);