Let's consider a few possible ways to speed this up.
Only look for prime factors
First of all, we know that even numbers (other than 2) are all composites, not primes. So, once we check for 2 as a factor, we can ignore all the other even numbers.
if (number % 2 == 0)
factors.push(2);
for (int i=3; i<limit; i+=2) {
if (number % i == 0)
factors.push(i);
}
This will normally approximately double speed in return for minimal effort.
Limit the search for factors
Note that in the loop above, I've specified the upper limit on the loop as limit
rather than number
. There's a reason for that. If two numbers multiply to give a third number, at least one of the factors must be less than or equal to the square root of the result. If it's a perfect square, then both of those can be the square root of the number. Otherwise, one is smaller than the square root, and the other is larger than the square root.
But we don't have to conduct a long search for the second number--once we know the factor that's smaller than the square root, simple division tells us the other factor.
So, we can search only for factors less than or equal to the square root, and using them, we can directly find the factors that are larger than the square root.
Also note one other point: there can only be (at most) one prime factor larger than the square root.
Consider using a sieve
Taking the two preceding points together, we can see another possibility. In particular, we can start by searching for primes less than or equal to the input number. Then we can test whether the number is divisible by them (and not any composites).
There's a really fast algorithm for finding all the primes up to some limit called the Sieve of Eratosthenes. It doesn't involve doing an division (which is a slow operation for computers). Instead, consider starting with a table of all the numbers up to the limit you care about. Starting from 2, add 2 to your list of primes numbers, then cross off all the multiples of 2. The look for the next number that isn't crossed off (3 in this case). Add it to the list of primes, then cross off all the multiples of 3. Then repeat--look for the next number that isn't crossed off (5), add it to the list of primes, and cross off all of its multiples.
When you've gone through the whole table that way, you have a list of all the prime numbers up to the limit you care about. Then in your original loop turns into something like:
for (int i=0; i<numberOfPrimes; i++)
if (number % primes[i] == 0)
factors.push(primes[i]);
Although it's written in C++ rather than JavaScript, I posted some code to implement this algorithm on SO some years ago. Most of the code isn't very specific to C++ though, so converting to JavaScript should be fairly easy.
This may fall within what you're referring to as a "nested algorithm" though--I'm not entirely sure what you mean by that.