I have a series of numbered javascript functions and I would like to loop through the functions based on a variable called total. If total is 3, I would like to run load1(data), load2(data), load(3) data; if it is 2 just the first two functions so on.
This seems simple enough, but I can't seem to get it working right. In the simplest form the code below works.
i = 1;
if (i <= total){load1(data);}i++;
if (i <= total){load2(data);}i++;
if (i <= total){load3(data);}i++;
if (i <= total){load4(data);}i++;
if (i <= total){load5(data);}
But I can't seem to be able to put that in a loop. I have tried the following:
Trying to put the functions in an array and calling them in a for loop based on this thread. //throws a function undefined error.
Call it inside a loop like this:
var f = new Function("return load"+i+"(data)")(); //throws a data not defined error
Any suggestions?
If loadX is global function, you could do like below:
for (var i = 1; i <= total; i++) {
window['load'+i](data);
}
Related
I have a for loop which will iterate through all choices and and set a value for them.
For some reason, when I run the code it does the first iteration, then skips to the last and does that one 3 times, or so according to the console.
code:
for (i = 0; i < 4; i += 1) {
console.log(i)
var generated = word
while (generated == word) {
generated = wordsJson.characters[Math.floor(Math.random() * wordsJson.characters.length)]
}
choices[i].innerHTML = translate(generated)
}
What I get in console:
0
(3) 3
This is my first time asking something on stackoverflow. If you need more information, please ask.
It appears that the variable i is getting modified outside of the for loop.
Typically you would want to declare your iterator variable (in this case i) so that it's scoped to the loop, which would look like:
for (let i = 0; i < 4; i += 1) { ... }
Note, specifically, the addition of let. Since you haven't done that, it means that either i is already explicitly declared somewhere or, if not, that you've created a new global variable i.
Since you've got code you haven't shown that also seems to relate to i (choices[i]) and methods that we don't know the exact function of (translate()) it's hard to say for certain, but that would be the first place to look.
If not, posting some additional code so we can see the other functionality would be helpful.
I’m doing an exercise on Code School, and I don’t understand how the loop works.
There is an i, but I don’t see it used. Normally you use it somewhere. Otherwise, what is the for loop for?
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
var start = 2;
var applyAndEmpty = function(input, queue) {
var length = queue.length;
for (var i = 0; i < length; i++) {
input = queue.shift()(input);
}
return input;
};
alert(applyAndEmpty(start, puzzlers));
It's used in the test to see if you have reached the end of the loop or not (the second part of the for statement).
Without the loop boundaries defined in the loop.
The loop will never end!
The variable is simply used to count the iterations of the loop. The loop ends after length iterations as kept track of by i.
In this case i serves no other purpose.
You don't have to use the i all the time, but its there if you need it. Normally if you dont use the i you use instead whats called a for-each loop instead. for-each is just a simpler way of writing a for loop without needing an explicit index variable.
Javascript doesn't have a simple for-each loop as part of the language, and I think they want to keep it as a for loop just to keep the lesson simple, but if you want to learn more about for-each in javascript, take a look at this question
It is being used - to ensure that the loop iterates length times.
If you are going to count from 0 to length - 1, you need something to keep track of the count, right?
I was just writing two JavaScript functions, one of which took in a long string, looped over it until it hit a space, then called the other function to print the input before the space into the DOM. The first function would then continue on with input after the space, hit a space, call the print function, etc.
In the process, I kept hitting infinite loops, but only if the string contained a space. I couldn't figure out why, since all the looping seemed to be set up properly. I ultimately figured out that my iterator variable was jumping scope out of my second function printMe and back into the first, readAndFeed, and because of the way the functions were set up, it would always come back as a lower number than the terminating value if there was a space involved.
The first function's loop looked like this:
function readAndFeed(content){
var output = "";
var len = content.length;
for(i = 0; i < len; i++)
{
console.log(i+" r and f increment")
if(content[i] == (" "))
{
printMe(output);
output = "";
}
else if(i==len-1){
output += content[i];
printMe(output)
}
else
{
output += content[i]
}
}
}
The second function is printMe(), and it looped over the string, broke it into three bits, looped over each of them separately (not in a nested fashion), and printed them to the DOM. I used similar loops in it, and I also used i as an iterator.
This would loop over strings with no spaces just fine, but if I threw a space in there, the browser would crash. I tried a bunch of different stuff, but ultimately (by logging the iterator values) realized something was up with i. What worked was changing the i in the printMe function to a j.
I'm confused; this doesn't seem like how I understand variable scope. The functions are defined separately, so it seems like the iterators should be local to those functions and not able to jump out of one into the other.
Here's a jsfiddle
Uncomment the "is an example" part at the bottom to crash your browser. Again, changing the i variables to j in the printMe function completely solved this, but whaaa?
When you don't declare a variable, it is implicitly global. Since you've not declared your loop iteration index i, it is global. If you do that in multiple functions, those globals will collide and one function will accidentally modify the other's variable.
The solution is to make SURE your local variables are declared with var as in:
for (var i = 0; i < len; i++) {
In your case, you need to fix both readAndFeed() and printMe() as they both have the same issue and thus they both try to use the global i. When you call one from the other, it trounces the original's use of i. Here's a fixed version of readAndFeed():
function readAndFeed(content) {
var output = "";
var len = content.length;
// add var here before i
for (var i = 0; i < len; i++) {
console.log(i + " r and f increment")
if (content[i] == (" ")) {
printMe(output);
output = "";
} else if (i == len - 1) {
output += content[i];
printMe(output)
} else {
output += content[i]
}
}
}
If you run your Javascript code in strict mode, then trying to use an undeclared variable actually causes an error (rather than implicitly make it a global) so you can't accidentally shoot yourself in the foot like this.
In your example, i is in fact a global variable. Any assignment without var statement to an undeclared variable declares an implicit global.
To make i local, just include var:
for (var i = 0; i < len; i++)
If you have a loop set up like
for (var i=0, t=myArray.length; i < t; i++)
once that loop is complete, is it ok to use the i and t vars in the next non-nested loop within the function?
I've been numbering my nested loops differently like
for (var i2=0, t2=anotherArray.length; i2 < t2; i2++)
but also doing the same for non-nested loops. I'm wondering if there's a need?
I ask, as Flash doesn't like it when you use the same vars, regardless if the second loop is not nested.
Thanks for your time and help.
Normally loop variables aren't used for anything other than doing calculations within the loop.
Even though the variable is available outside the loop, normally it isn't used.
Sometimes you might set another variable to the exit value of a loop variable.
for(i=0;i<max;i++){
....
if (some exit condition that leaves the loop early){
//should assign value here instead of outside the loop
exitvalue = i;
break;
}
}
//exitvalue = i; //can assign the value of i here (try to avoid this)
Therefore it is usually quite safe to reuse loop variables.
The var i or t is declared in the scope where the loop is in.
Javascript uses "Hoisting".
So,
for (var i=0, t=myArray.length; i < t; i++) // first loop
is equal to:
var i,t;
for (i=0, t=myArray.length; i < t; i++)
So, when you use the same variables next time in a non-nested loops, like this:
for (var i=10, t=myArray.length; i < t; i++) // second loop
the i and t are already hoisted and hence you are just doing something like this:
var i = 0;
i = 10;
So it is okay to use i and t vars in the next non-nested loop.
During the course of designing a small API at work and trying to make my functions as flexible as possible I decided to start adding checks for whether arguments are passed, and then based on that, do different things. So when the function is called with a number, the function uses the number as an index in an array. If no number is passed, I wanted the function to call itself as many times as the length of the array. However I get the call stack error. I have boiled the problem down to the recursion aspect of the function, which I'm listing below. The thing that is strangest to me is this...
THIS CAUSES ERROR
function testing(a){
if(!a){
for(var i = 0; i < 3; i += 1){
testing(i);
}
}else{
alert(a);
}
}
testing();
THIS DOES NOT CAUSE ERROR
function testing(a){
if(!a){
for(var i = 0; i < 3; i += 1){
testing(5);//Just adding hard coded number instead
}
}else{
alert(a);
}
}
testing();
I'm trying to understand why passing the var in the call throws an error. It seems that if the js engine can hold the initial function call in memory in order to make the for loop work properly why couldn't it hold a reference to i while calling itself? I feel like I am missing something fundamental here. I've tried lots of rewrites involving things like:
testing(function(i){return i;}(i));
All to no avail. This is driving me crazy and I would like to understand what is going on here.
if a===0 it is false, that means you have an infinite loop
for more details, read this and this (thanks #yochannah )
This works just fine.
function testing(a){
if(!a || a == 0){
for(var i = 1; i <= 3; i++){
testing(i);
}
} else {
alert(a);
}
};
testing();
Obviously there's no need to both start the loop counter off of 1 AND checking whether a == 0, but both methods would work.
EDIT: Another check you can have is (a == undefined).
The thing is that a variable that returns 0 is false when you check it with !.