Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not access var i like this and how do I work around it?

Tags:

javascript

I was just fiddling around and was just wondering if it would be possible to access the I variable somehow in this loop.

var string = 'abcdefghij';
for(var i = 0; i < 10; i++){
    window[string[i]] = function(){
        console.log(i);
    };
}
a();

Obviously for many reasons I wouldn't do this with the global scope normally, but I'd like to use this as an example.

Would there be a way to still access the i var from inside this function?

like image 635
Puddingboy Avatar asked Dec 13 '25 05:12

Puddingboy


2 Answers

The problem is that you are calling i in another scope, where it is not defined.

This is not completly correct yet:

var string = 'abcdefghij';
for (var i = 0; i < 10; i++) {
  window[string[i]] = (function(i) {
    return function() {
      console.log(i);
    }
  })(i);
}
a()

This self-executing function will basicly copy the variable i into it's own scope, so it can be used later on.

But, when you try to execture the function i above you will notive that it throws an error Uncaught TypeError: i is not a function. This is because you are using the same global variable in the for loop var i as you are setting the function i to. To avoid this problem use the same trick again around the loop. However be warned, as soon as you use a for loop or any global variable again that has the same name as one one the dynamicly defined function, you will get unexpected problems again.

var string = 'abcdefghij';
(function() {
  for (var i = 0; i < 10; i++) {
    window[string[i]] = (function(i) {
      return function() {
        console.log(i);
      }
    })(i);
  }
})();

i()
like image 79
CoderPi Avatar answered Dec 15 '25 17:12

CoderPi


The best solution is to use let instead of var. And it's a good pratice. With let, variables are defined within the closest block scope. As a result, they will not be overwritten after each iteration.

'use strict';
var string = 'abcdefghij';
for (let i = 0; i < 10; i++) {
  window[string[i]] = function() {
    console.log(i);
  };
}
a(); //0
like image 42
Lewis Avatar answered Dec 15 '25 19:12

Lewis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!