21

Since according to What's the difference between using "let" and "var" to declare a variable?, the let keyword has a smaller scope than var when used in a for loop. Does this mean that of all the places where 'for (var i=0...' the actual correct way should be to use let? I can't imagine a case where a developer who was using 'for (var i=0...' would want to have the var i still be visible outside the for loop, meaning that all 'for (var i=0...' are wrong and the correct way is 'for (let i=0...'? Just a yes or no question.

function allyIlliterate() {
    //tuce is *not* visible out here

    for( let tuce = 0; tuce < 5; tuce++ ) {
        //tuce is only visible in here (and in the for() parentheses)
    };

    //tuce is *not* visible out here
};

function byE40() {
    //nish *is* visible out here

    for( var nish = 0; nish < 5; nish++ ) {
        //nish is visible to the whole function
    };

    //nish *is* visible out here
};
Community
  • 1
  • 1
eternalminerals.com
  • 395
  • 1
  • 4
  • 14
  • Judging by the complete split in answers, both with good reasons for and against, I think this might qualify as "primarily opinion-based." – ajm Aug 31 '15 at 14:57
  • @ajm I mostly agree, though the question as worded clearly asks whether "all the for loops" are "wrong", and I don't think that's a matter of opinion. – Pointy Aug 31 '15 at 15:01
  • That's true. It will be interesting to see if the answers maintain the same 50/50 split. :-) – ajm Aug 31 '15 at 15:03

3 Answers3

15

let is introduced in Ecma Script 6 - the new javascript version - which is still in development at the time of this writing. Therefore, using var will get you across more browsers for the time being.

On the other hand, I urge people to use let instead of var from now on. I would go ahead and list the reasons but you have already have a link in your post with a great explanation in it. Long story short, let helps you avoid the variable hoisting in javascript and keep your variables' scope at just where it needs to be.

update

I've forgotten about this post until I recently got an upvote. I'd like to update this statement. I personally use const as much as I can these days. If you get into linting your code, which I highly recommend, and use something like airbnb lint rules, it will also tell you to use const. It will make your variables a constant so you will not be able to mutate them once you set their value thus it is not applicable in all cases. const and let also have advantages in terms of scope over var and it is well worth a read. My hierarchy of usage goes as such const > let > var

ODelibalta
  • 2,194
  • 1
  • 18
  • 28
10

Yes, you would want to use let there as it will be scoped only to that block.

Additionally, using let in this way will let you avoid accidentally creating a closure if you are calling a function in your loop and passing the counter as a parameter.

EDIT: Maybe this should be better put as: Ask yourself if you need to access the value of your variable outside of the loop. If you do, use var; in all other cases, use let.

ajm
  • 19,795
  • 3
  • 32
  • 37
8

The answer is "no", in my opinion:

function doSomething( anArray ) {
  for (var i = 0; i < anArray.length; ++i) {
    if (someTest( anArray[i] ))
      break;
  }
  return i === anArray.length ? "test failed" : "test succeeded";
}

That's not the prettiest thing in the world, but checking an iterator variable after a loop is at least somewhat idiomatic. It's also possible that a var i in one for loop is taken advantage of in the same function in a later for loop that doesn't repeat the var.

Now, whether code like that should be improved in a way that happens to take advantage of let is another question. It should be clear however that blindly replacing such uses of var with let in an existing codebase would be seriously unwise.

Going forward, it's certainly a good idea to keep variable scoping as constrained as possible, but dogmatic rules like "always use let and not var in for loops" can't possibly take into account all the programming problems you may encounter. A "best practice" is "best" until it isn't.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    Actually, it's quite easy to change that function so you can use ```let``` instead of ```var``` and simplify it by removing the ```? :``` operator in the process. Simply set a default return value before you enter the loop and update it before the ```break``` statement. – Arjan Aug 31 '15 at 15:00
  • 1
    @Arjan I understand that; the point is, it's not "wrong" as it is. Would it be better if it were re-written? Well, it's a rare piece of code that wouldn't :) – Pointy Aug 31 '15 at 15:02
  • 3
    Actually you can use let INSTEAD of var in this case. Just move out declaration of i out of for loop (put such line above for loop "let i;" and use the declared i in for loop like this: "for (i=0; i<...)"). This would make your intention more clear as i is explicitly moved out, and also you'll end up without "var"-s in the code so risk of hoisting is not a problem anymore. – Just Shadow Mar 30 '18 at 07:46