-3

I am a javascript learner Hear is my javascript

I have a javascript function named get(); which i call it onload.

function get() {
  for (var i = 1; i <= 5; i++) {
    setTimeout(function() {
      console.log('Value of i : ' + i);
    }, 100);
  }
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
</head>

<body onload="get();">
</body>

</html>

The expected output is

Value of i : 1
Value of i : 2
Value of i : 3
Value of i : 4
Value of i : 5

where as i am getting

 Value of i : 6

Not able to figure out what is exactly is wrong .

SAMUEL
  • 8,098
  • 3
  • 42
  • 42
KishanCS
  • 1,357
  • 1
  • 19
  • 38
  • it's not a duplicate as long as you dont know what to search for. To the experienced javascript-developer, this is a duplicate, yes, but not to the novice. – Tobias Gassmann Mar 03 '17 at 09:20
  • @KishanCS You cannot. There are answer on this post. This is one major reason why answering a dupe is considered as bad. This will serve as a redundant post. – Rajesh Mar 03 '17 at 09:24
  • 1
    guys have some mercy on down votes.. – KishanCS Mar 03 '17 at 09:28
  • this is a perfectly innocent question, and from the viewpoint of the person how asked this question, it is not a duplicate at first sight. After having understood the problem it is of course a duplicate.Nevertheless it makes sence to have it under the topic of "setTimeout not working", because this is the place where this problem frequently occurs. – Tobias Gassmann Mar 03 '17 at 09:32
  • @KishanCS Your previous comment *i dint new asking at stack overflow would be so much mistaken* earned you 1 downvote. Please take this as a lesson to search properly before you post and to keep your cool. – Rajesh Mar 03 '17 at 09:32
  • 1
    how should he search for the problem if he does not know the right vocabulary? – Tobias Gassmann Mar 03 '17 at 09:32
  • I understand your concern to learner thanks @ Tobias Gassmann – KishanCS Mar 03 '17 at 09:35
  • @TobiasGassmann I'm just curious about the reason you are getting so much offended? Yes I agree OP was not aware about closures and he was not able to search properly, but the issue is not in `setTimeout`, its in `for`. Removing that and adding a function would still yield the same. Also about downvotes, you get all your lost reps due to downvote if you delete it. But because some users don't wish to keep the discipline of not answering/ deleting answer for dupe, OP will have to bare this loss – Rajesh Mar 03 '17 at 09:37
  • 1
    @Rajesh I don't know, I did not get enough sleep I guess :-) Nevertheless I think it is good to have multiple different titles of questions leading to the javascript-loop-issue, because I myself had a hard time solving this 10 years back, because I did not know what to google – Tobias Gassmann Mar 03 '17 at 09:41
  • @KishanCS You don't have to be. Please read my previous comment. As said its not entirely your fault. You made an honest mistake which was followed by mistakes by others and not its you who will have to bare the consequence. – Rajesh Mar 03 '17 at 09:41
  • @TobiasGassmann Even that would do no good. In my understanding, OP's approach was right. Yes its a dupe and you will get downvotes but on deletion, you get it back. Its upon us to **not** answer dupes and if you are not aware about this being a dupe, you **should** delete your answer, unless its points to something that dupe link does not cover. – Rajesh Mar 03 '17 at 09:44
  • 1
    @Rajesh I think we both are in this well known "Someone on the internet is wrong"-Situation on an otherwise perfectly nice Friday :-) – Tobias Gassmann Mar 03 '17 at 09:49

2 Answers2

3

The correct approach to to do this is :

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
</head>
<script>
    function get() {
        for (var i = 1; i <= 5; i++) {
            setTimeout(function(x) {
                console.log('Value of i : ' + x);
            }(i), 100);
        }
    }
</script>
<body onload="get();">
</body>
</html>

Notice the (i) in :

    setTimeout(function(x) {
        console.log('Value of i : ' + x);
    }(i), 100);
}

this is how you pass values to a settimeout function.

Shakti Phartiyal
  • 6,156
  • 3
  • 25
  • 46
1

You can use let that has its own scope or you can create a closure there.

Using let

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
</head>
<script>
    function get() {
        for (let i = 1; i <= 5; i++) {  
            setTimeout(function() {
                console.log('Value of i : ' + i);
            }, 100);
        }
    }
</script>
<body onload="get();">
</body>
</html>

Closure snippet

<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">
</head>
<script>
  function get() {
    for (let i = 1; i <= 5; i++) {
      setTimeout(((function(i) {
        return function() {
          console.log('Value of i : ' + i);
        }
      })(i)), 100);
    }
  }
</script>

<body onload="get();">
</body>

</html>
Vladu Ionut
  • 8,075
  • 1
  • 19
  • 30
  • this worked for (let i = 1; i <= 5; i++) //use of let can you explain – KishanCS Mar 03 '17 at 09:17
  • 1
    it's not a duplicate since the person who asked the question is unfamiliar with the concept of clusures and therefore suspected an error in the setTimeout-Function. – Tobias Gassmann Mar 03 '17 at 09:22
  • 1
    @TobiasGassmann its not about familiarity. A dupe is considered when question is similar to some other post and solution in that post would solve the problem. – Rajesh Mar 03 '17 at 09:25
  • @TobiasGassmann Funny thing about your point is, if OP knew about closures, there wouldn't be a post. Its only because he didn't know, this question exists. :-p – Rajesh Mar 03 '17 at 09:30
  • exactly :-) this closure-loop-thing is hard to google like this post examplifies: http://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue :-) – Tobias Gassmann Mar 03 '17 at 09:37