DEV Community

Discussion on: Declaring JS Variables in 2019

 
simevidas profile image
Å ime Vidas

I guess const makes (more) sense in large teams that work on large code bases (emphasis on I guess). I would like to see some practical evidence. If somebody was in a concrete situation where const saved them (and their team) from a nasty bug, I would like to read about it, so that I can get a feel of const’s usefulness.

If I started using const, I would have to decide every time when I declare a new variable, whether or not it should be re-assignable. This mental task seems unnecessary and annoying to me. I would rather spend my brain power on the actual problems that I’m trying to solve in my code.

Thread Thread
 
kenbellows profile image
Ken Bellows • Edited

Since I've switched to using const, I find that I almost never use let. In fact, the rarity of let makes it stand out in the code when it is used; it feels like a beacon to anyone reading the code that this variable is special, it's going to be updated later.

But I almost never update variables anyway. There are basically two cases where I use it:

  1. In an old-fashioned for (let i=0; i<num; i++) loop
  2. In a case where I'm setting the value inside of a block, either a complicated conditional situation or a try ... catch situation:
let x;
switch (some_var) {
  case 0:
    x='a';
    break;
  case 1:
    x='b';
    break;
  default:
    x='c';
}
let x;
try {
  x = methodThatMightThrow();
}
catch(_) {
  x = fallbackVal;
}

Neither of those are very common in my code, so I basically never use let.

Thread Thread
 
samthor profile image
Sam Thorogood

I'm glad to hear you're on the same page as me! I like the shining beacon analogy.

For me, both those examples often warrant extracting behavior to some helper function, but I understand how you're using them there, too.

Thread Thread
 
simevidas profile image
Å ime Vidas

That sounds like a solid approach. I’m surprised that const works fine in (the header of) for-of statements but not in for.

Thread Thread
 
kenbellows profile image
Ken Bellows

Yeah, the difference seems to be that in a for ... of loop like this:

for (const thing of myThings) { /*...*/ }

you're essentially grabbing an iterator at the start of the loop, i.e. myThingsIter = myThings[Symbol.iterator](), then at the beginning of each loop running const thing = myThingsIter.next(). It seems to desugar to something like this:

const myThingsIter = myThings[Symbol.iterator]()
while (true){
  const {done, value: thing} = myThingsIter.next();
  if (done) break;

  /* ... */
}

You're always assigning a whole new value to the loop variable as opposed to modifying the loop variable as is typical in a classic for (let i=0; i<n; i++) loop.

Really the only reason you need a let in that loop is because you're reassigning the value with i++, equivalent to i = i+. In theory you can use a const if you're doing something super unusual, like using an object as your loop variable and modifying a property of it:

for (const o = {count: 0}; o.count < n; o.count++) {
    /* ... */
}

I don't know why anyone would ever want something like this, and there would undoubtedly be cleaner ways to write the code, but it works. You're never reassigning o, so no problem with it being a const.