Opa, só para entender melhor. Para contornar este problema do estouro de pilha eu poderia otimizar a função recursiva, algo como:
function tailRecursiveFat(n, resultado = 1) {
if (n == 0) {
return resultado;
}
return tailRecursiveFat(n - 1, n * resultado);
}
Mas, coloquei ela no site de testes, e para este exemplo que você passou o loop for ainda é mais rápido.