Unexpected infinite loop - javascript

This code runs for infinity, why?
function f(n){
i=0;
if (n==2){
while(i<2){
f(i);
i++;
}
}
}
if n!=2 the function should do nothing
and if n equals 2 the function calls f(0) and f(1) so it should stop after that
but you only get infinite loop when you run it.
any one could tell why?
edit: there is nothing outside the function.
and no need for better code.Just asking why.

You can fix it by changing
i=0;
to
var i=0;
Your i variable is global (or at least its scope is external to f, so it's shared by all calls of the function). When n is initially 2, you enter the loop and this loop always resets i to 0 just before the increment. The sequence you have is thus
i = 0 // start of f
// enters loop for the first time with f(0)
i = 0 // start of f
i = 1 // i++
i <2 so loop again
i = 0 // start of f
i = 1 // i++
i <2 so loop again
i = 0 // start of f
i = 1 // i++
i <2 so loop again
i = 0 // start of f
i = 1 // i++
i <2 so loop again
i = 0 // start of f
i = 1 // i++
...

i is global. Declare it with var instead to keep it local to each instance. Otherwise, it is constantly reset to 0, so your while loop never ends.

Because you got f(i) all the time with i = 0. So when you are doing a loop, you are going to do f(0) indefinitly ! (same for every i) Just put a var on your i to stop your loop

Can you try this, i=0 is global variable, reason for f(i) setting the value each and every time along with Global variable, so you need to use var i=0; for initialize the i every time.
function f(n){
var i=0;
if (n==2){
while(i<2){
f(i);
i++;
}
}
}

Every time f() is called, i is set back to 0. Since you didn't do var i = 0, that means that i is global! Every time f() is called, the same value of i is used.
When you call f(2), you start a while loop. Every time you call f(i), you are re-setting i to 0. So the while loop never ends.
You need to make i local:
function f(n){
var i=0;
if (n==2){
while(i<2){
f(i);
i++;
}
}
}
This way every time f() is called, it creates its own i variable.

Related

why output this result when I make break to label in iteration?

I'm a newbie of javascript, and I certainly coundn't understand this output when I learn for statement..
foo: for(var i=0; i<3; i++){
console.log(i);
if(i==1){
break foo;
}
}
and I get some print like this..
0
1
to be honest, I dont know what happend here, I think that may throw error here because too deep iteration may be caused..
I want to get this result actually
0
1
0
1
0
1
...
maybe it's a stupid question, but I indeed want to get answer.
could anybody help me..
for(var i=0; i<3; i++){
console.log(i);
if(i==1){
break foo;
}
}
You are running a for loop which is iterating from 0 to 3 (excluded).
in each iteration it print the value of i.
if value of i is 1 then it break from loop
first iteration: i=0; print 0 continue as 0 != 1
second iteration: i=1 print 1 break as 1 == 1
lean more about for loop
Your loop is trying to output i while it is less than 3 and increment it by one for every iteration.
the if (i == 1) statement is true in the second iteration so the break gets executed which "exits" the loop.
An infinite loop will do it.
var v = 0;
while (true) { // <-- this runs forever!
console.log(v);
v ^= 1;
}
or with a limit of 1000 loops
var v = 1000;
while (v) {
out(v % 2);
v--;
}
// just for dispaying the result
function out(s) {
var descriptionNode = document.createElement('div');
descriptionNode.innerHTML = s + '<br>';
document.getElementById('out').appendChild(descriptionNode);
}
<div id="out"></div>
Actually break statement is used to get out of the loop.
As we know earlier for loop loops execution until condition (here i<3) is true. if the condition gets false then it terminates ie., when the i is incremented to 3.
But, the if condition to be checked is i==1 so whenever i is incremented to 1 the for loop gets terminated by break statement.
Each time the incremented value of i is printed in the console of the browser as a log. until the termination.
Your code does:
print i
then break
it will print 0 1 and then break the loop.

JavaScript Higher Order Function loop/recursion/confusion

Implement a function that takes a function as its first argument, a number num as its second argument, then executes the passed in function num times.
function repeat(operation, num) {
var num_array = new Array(num);
for(var i = 0; i < num_array.length; i++){
return operation(num);
}
}
//
// The next lines are from a CLI, I did not make it.
//
// Do not remove the line below
module.exports = repeat
RESULTS:
ACTUAL EXPECTED
------ --------
"Called function 1 times." "Called function 1 times."
"" != "Called function 2 times."
null != ""
# FAIL
Why doesn't this work?
I am assuming that I am starting a function called repeat. Repeat has two parameters and takes two arguments.
For the loop I create an array which has a length which is equal to the num passed in.
I then start a for loop, setting a counter variable i to 0. Then I set a conditional which states that i should always be less than the length of the num_array which was created earlier. Then the counter i is incremented up by one using the ++.
For every time that the conditional is true, we should return the value of calling running the function operation and passing the num as an argument.
The last two lines allow for easy running of the program through command line with pre programmed arguments being used.
Thank you for your time!
The return statement is breaking out of the function on the first iteration of the loop. You need to remove the return, and just call the function like this:
function repeat(operation, num) {
for(var i = 0; i < num; i++){
operation(num);
}
}
Note that I have removed the creation and iteration of the array, you do not need it for what you are doing here.
Also your initial question does not specify that you need to pass num to the function (but you do list it in your steps below), so you may be able to just do operation() instead of operation(num).
You probably want something like the below, rather than returning the result of the function operation(num) you want to store the value in teh array. return in a loop breaks out of the loop, so it would always only run once..
function repeat(operation, num) {
var num_array = new Array(num);
for(var i = 0; i < num_array.length; i++){
num_array[i] = operation(num);
}
}
//
// The next lines are from a CLI, I did not make it.
//
// Do not remove the line below
module.exports = repeat
If you are asking why the loop is not running, it's because you have to run the function after defining it (I'm assuming you are not already calling the function somewhere else).
Once calling the function repeat you will see that it is exiting after one iteration. This is because you are returning the operation - returning causes the function to end. To stay in the loop you just need to call operation(), without the return.
Also you don't need to create an array, you can just use the counter you are defining in the for loop.
So the code would look something like this:
var op = function(arg) {console.log(arg);},
n = 5;
function repeat(operation, num) {
for(var i = 0; i < num; i++){
operation(i);
}
}
repeat(op ,n);
// The next lines are from a CLI, I did not make it.
//
// Do not remove the line below
module.exports = repeat

Trying to get a while loop to alert/log a string 3 times but instead it only logs once

The tutorial I'm following says that I need to use a while loop to log to the console "I'm looping!" three times without actually calling the console.log command three times. This is what I have, however when I run it, it only logs the string once and if I call my loop function 5 or more times, then it doesn't log at all.
var count = 0;
var loop = function(count){
while(count < 4){
console.log("I'm looping!");
count++
}
};
loop(3);
The count argument you've declared in your function shadows the count variable outside the function. ("Shadows" = "hides", e.g., the argument makes the variable inaccessible by name.) Since you're passing in the value 3 for the argument, the loop only runs once, as 3 < 4 but then you incremented it and 4 < 4 is false.
If you want to use the count variable declared outside the function, change the name of your argument and/or don't provide one at all:
var count = 0;
var loop = function(){
while(count < 4){
console.log("I'm looping!");
count++
}
};
loop();
The first time you call loop, it will loop four times (once for 0, for 1, for 2, and for 3). Any subsequent calls won't loop at all (unless you change count).
If you want to loop up to a given number of times, but never let count be >= 4, use a different name for the argument:
var count = 0;
var loop = function(c){
var i = 0;
while(count < 4 && i < c){
console.log("I'm looping!");
count++;
++i;
}
};
loop(3);
The first time you call that, it will loop three times, once for 0, then for 1, then for 2. Then, i is == c and so the loop does not continue. If you called loop again, it would run up to one time, at which point count would be 4 and the loop body would never be run.

Variable scope in javascript when iterating through a stack

I'm baffled. Could someone please explain to me why this produces an infinite loop?
var constant = 4;
var stack = new Array();
stack.push(0);
stack.push(1);
loop1();
function loop1(){
for(i = 0; i < constant; i++){
loop2(i);
}
}
function loop2(num){
for(i = 0; i < stack.length; i++){
console.log(i);
}
}
​
Fiddle: http://jsfiddle.net/elclanrs/tywV9
I suspect it has something to do with Javascript function-level variable scope, but that's as far as my guess goes.
When you don't declare a variable with the var keyword, the variable is global, so loop2 and loop1 are using the same (global) i variable. Every time loop2 is called, i gets set to 0 and then is incremented up to stack.length, which is 2. This means that every iteration of loop1 will end with i=2, which gets incremented to 3 but never reaches constant which is 4.
If you change your for loops to be for (var i = 0; ...) instead of for (i = 0; ...) then this should no longer loop infinitely.

Why JavaScript alerts allways 4 in when for-loop is for 3?

Why this JavaScript alerts allways 4 in when for-loop is for 3?
// alert
function reOrderLayers(layerToaAlter) {
alert(layerToaAlter);
}
// prepare
var laCount;
for (laCount = 1; laCount <= 3; laCount++) {
var la = document.getElementById("layerChanger"+laCount);
la.addEventListener("click", function () { reOrderLayers(laCount) });
}
When loop is finished means i is >3, to preserve particular number in function call use closures:
la.addEventListener("click", (function(count) { return function () { reOrderLayers(count) } })(laCount) );
The for loop continues until laCount == 4 (the last time the loop is executed the value is 3 and then it is incremented to 4 so that the loop test fails). Therefore the value is 4 after the for loop.
You didn't call reOrderLayers immediately in the loop but constructed a function literal. The literal will have a closure and it refers to the laCount variable in the environment which will be 4 when the click event is eventually fired.
Because when you click on the element; for loop is already finished and current value of laCount would be 4;
you should create a context to save laCount for each layerChanger:
function reOrderLayers(layerToaAlter) {
alert(layerToaAlter);
}
function context(la, laCount){
la.addEventListener("click", function () { reOrderLayers(laCount) });
}
// prepare
var laCount, la;
for (laCount = 1; laCount <= 3; laCount++) {
la = document.getElementById("layerChanger"+laCount);
context(la, laCount);
}
Because:
var c = 0;
for(c = 1; c <= 3; c++) {};
alert(c); // alerts 4.
During the first 3 iterations the for loop goes into the body and conducts the code you have inside. Once you're on the 4th iteration, lacount get incremented and the condition fails, so that you don't go into the loop again.
If you needed lacount to be 3 for some reason, you could try setting the initial for loop condition to i < 3.

Categories