This question already has answers here:
How do I pass the value (not the reference) of a JS variable to a function? [duplicate]
(6 answers)
Closed 8 years ago.
I have a script that needs a function to be run multiple times per object, but the number of objects is set in a variable by the user.
It would work like this
dothis(1);
dothis(2);
dothis(3);
However this doesn't work
for (var i = 0; i < howMany; i++)
{
setInterval(
function()
{
dothis(i);
},
(Math.floor(Math.random() * 10) + 1)
);
}
You need to snapshot the value of i in a local scope otherwise it gets dynamically 'regenerated' at execution time, which means the value would then always be howMany, since the CPU lock, created by the main function, prevents your setInterval/setTimeout functions to execute before the loop is ended.
for (var i = 0; i < howMany; i++)
{
setInterval(
function(j)
{
return function() { dothis(j); };
}(i),
(Math.floor(Math.random() * 10) + 1)
);
}
See How do JavaScript closures work? for further reference.
Related
This question already has answers here:
how do I create an infinite loop in JavaScript [duplicate]
(2 answers)
Execute JavaScript code stored as a string
(22 answers)
Calling a function every 60 seconds
(15 answers)
Closed 1 year ago.
I'm trying to make a function that runs a specified piece of code forever. How can I do this?
Example:
function forever(code) {
for (let i = 1; i > 0; i++) {
//Run code from variable here
}
I've tried:
function forever(code) {
for (let i = 1; i > 0; i++) {
code
}
Just use the while loop.
function forever(code) {
while (true) {
console.log("Running forever");
}
}
forever();
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 3 years ago.
I have 2 simple code snippet about for loop involving let and var separately.
First code which has a variable declared with let
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
so it will show o/p like this
0123456789
but if I replace let with var like this
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
it will print 10 for ten times.
I know it is something related to function level scope and block-level scope, but want to clearly understand step by step process of execution.
Thanks in advance.
The reason why you are only printing 9 is that the callback function is executed after the loop is done. Which means that i is 9.
You can:
If you are trying to print 1 - 10 after 1 sec, you can loop in the callback function. Like:
setTimeout(function() {
for (var i = 0; i < 10; i++) { //Put the loop inside the setTimeout db function.
console.log(i);
}
}, 1000);
If you are trying to print every one sec, you can pass the i as the 3rd parameter on setTimeout
for (var i = 0; i < 10; i++) {
setTimeout(function(o) { //Receive it on variale o
console.log(o);
}, 1000 * i, i); //Pass the i as third parameter
}
Doc: setTimeout
This question already has answers here:
setTimeout() method inside a while loop [duplicate]
(8 answers)
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 3 years ago.
I want to open a link every 3 seconds. I am using the setTimeout function, but it doesn't work. All links will be opened once.
for(var i=0; i < url.length-1; i++) {
setTimeout(function(){
linkaddress=url[i];
window.open(linkaddress);
}, 3000);
}
Use "let" instead of "var" for block level scoping, and then multiply your time by i variable (more info). Code:
var url = ["https://domain1.com","https://www.domain2.com"],
timeout = 3; // Time in second
for(let i=1; i <= url.length; i++){
setTimeout(function(){
linkaddress=url[i-1];
window.open(linkaddress);
}, i * timeout * 1000);
}
EDIT: Note that this code uses EcmaScript 6 features
Use setInterval instead
url = ['a', 'b', 'c'];
var i = 0;
var interval = setInterval(function() {
if (i <= url.length - 1) {
///linkaddress = url[i];
//window.open(linkaddress);
console.log(url[i]);
i++;
} else {
clearInterval(interval);
}
}, 3000);
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 4 years ago.
I have a question which might sound silly. In the code below there are 2 console.log(i) statements. I want to know why does the second console.log(i) statement returns value of 2 and not 1 as the former on the first iteration (i.e. 1st statement i=n, 2nd: i=n+1). Shouldn't both be equal to 1 until the end of the loop?
function toggleWrapper(){
var el1 = document.querySelectorAll('[class="tCell entryDesc"]');
for (var i = 1; i < el1.length; i++) {
console.log(i);
el1[i].addEventListener('click', function(ev){
console.log(i);
var el2=document.querySelectorAll('[class="additionalInfoContainer"]');
if (el2[i-2].clientHeight) {
el2[i-2].style.maxHeight = 0;
}
else{
el2[i-2].style.maxHeight = el2[i-2].scrollHeight +"px";
}
},
false);
}
}
The problem is that the variable i, within each of your addEventListener() functions, is bound to the same variable outside of the function. simply change your for loop to :
for (let i = 1; i < el1.length; i++)
In the loop with let based index, each iteration through the loop will have a new value of i where each value is scoped inside the loop, so your code would work fine.
i think is something in your code because if you try to make a for loop with two "console.log()" it doesn't do that
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript infamous Loop problem?
For some reason I get "6" inside my function here for every div element:
for(var i = 1; i <= 5; i++){
$('<div class="e-' + i + '"></div>').appendTo(something).click(function(){
alert(i); // <-- it's 6. wtf??
});
}
instead of 1, 2, 3, etc.
The class on the other hand it appears to be correctly set..
What am I doing wrong?
Your for loop is being executed at page load time. The alert only fires when there's a click event which is happening after the for loop has finished. Hence the value of i is now 6.
1) Page loads, for loop does its stuff...
2) Sometime later a click event is fired. the value of i at this time is 6 because the forloop has already completed.
The problem is that you need to create a closure to capture the value of i at the time you bind the click function.
Try this:
for(var i = 1; i <= 5; i++)
{
$('<div class="e-' + i + '"></div>')
.appendTo(something)
.click(function(value)
{
return function() { alert(value) };
}(i));
}