I just launched a new course on ES6! Use the code WESBOS for $10 off.

Strengthen your core JavaScript skills and master all that ES6 has to offer. Start Now →

Is var Dead? What should I use?

We’ve learned about let and const — what they do, and how they’re scoped. We also know when they can be reassigned and when they cannot, but there’s a question: What Should I actually use?

That’s a bit of a hot topic in the community right now, because some people prefer to still use var. Some people are saying, “var is dead!” Some say, “Use let.” while others always use const.

var isn’t dead – it still does what it always has done — it’s function scoped and you can reassign or re-bind it. You may very well continue to choose it. There isn’t a right answer here, just opinions. Check them out and make your own decisions.

I’m just going to go over two of the leading opinions here. These are both done by some very, very smart people in the JavaScript scene, so I’ll let you pick your own.

This one, by Mathias Bynens, is how I do it. He says that “const is not about immutability where you can change the properties.”

Later on in the article he talks about let vs. const

  • Use const by default
  • Use let only if rebinding is needed.
  • var should not be ever used in ES6.

Whenever you make a variable, assume it’s const. Only use let if you need to update the value of the variable. You can use const to keep it the same value.

Another popular opinion here is from Kyle Simpson, and he also writes a whole bunch of awesome JavaScript books.

  • Use var for top-level variables that are shared across many (especially larger) scopes.
  • Use let for localized variables in smaller scopes.
  • Refactor let to const only after some code has to be written, and you’re reasonably sure that you’ve got a case where there shouldn’t be variable reassignment.

He says, basically, Use var to share larger scopes so you can put them inside of your function, and use let in smaller scopes. If you realize later that you need to update a value, you’d have to go back and make it a let instead of a const. If you use let, it’s easier to go back and refactor them to const.

Both of those are very valid opinions. I’ll let you make your own choice on that, but through the ES6.io series, I’ll be using const by default, let whenever I need to reassign a variable, and stay away from var entirely.

This entry was posted in ES6, JavaScript. Bookmark the permalink.

23 Responses to Is var Dead? What should I use?

  1. Dalton Santos says:

    Here’s a case that one could like:

    If your variable is function scoped you can write:
    “`
    if (condition) {
    var value = ‘some value’;
    } else {
    var value = ‘another value’;
    }

    console.log(value);
    “`

    Instead of:
    “`
    let value;
    if (condition) {
    value = ‘some value’;
    } else {
    value = ‘another value’;
    }

    console.log(value);
    “`

    • wesbos says:

      Yep exactly – var still has that utility – can read a little nicer there.

    • Yann says:

      Why not :
      “`
      let value = ‘another value’;
      if (condition) {
      value = ‘some value’;
      }

      console.log(value);
      “`
      in your case ?

      Defining var in a sub level is not very elegant…

      • eric says:

        That’s how I usually do it as well, but sometimes assigning it in the else or else if makes sense if you want to be more explicit about the logic flow.

    • Tony Quetano says:

      This hoisting black magic only doesn’t seem like black magic because we’ve all gotten used to it. If you look at it without experienced developer eyes, relying on hoisting is a recipe for at best code confusion, at worst side effects and brittleness. Death to var is death to implicit magic, which I fully support.

        • Boris A says:

          Hosting function statements is great.
          Variables being hoisted from within if blocks (for example) is really a bad idea IMHO.

          That is why declaring a function inside of such block is invalid.

        • bsherrill says:

          This is all just my opinion, and I totally respect everyone’s individual choices.

          ===

          I do see how it can look nicer, but I don’t think I could ever do it. I have a professor who does it, and it honestly drives me crazy.

          Hoisting I think is unique to javascript (I could be wrong). A mental paradigm most people have is that code runs top down. Using something before it’s defined just feels odd.

          This does mean you have to scroll down to the bottom after everything is defined, but honestly that shouldn’t be much scrolling. If you do end up doing a lot of scrolling, then maybe you could break stuff into smaller modules.

    • Karl says:

      Don’t linters complain about that by default?

    • Cory House says:

      I’d just use a ternary.

      const value = condition ? ‘some value’ : ‘other value’;

      Much higher signal to noise ratio.

      • Daniel Earwicker says:

        Exactly this. The ultimate aim, to compute “value”, is made obvious. Another win for “prefer const”. Aim to write definitions of immutable named values, rather than mutable state. Much harder to get wrong, or in the wrong order etc.

  2. Param says:

    I try to use avoid mutation as much as possible. I’d write the following:

    const value = condition ? ‘some value’ : ‘another value’;

  3. Thomas says:

    I’d prefer a mix between the two approaches. Never say never, so I would like to keep var in the game for larger scopes just like Kyle Simpson suggests. However, I like the idea of using const as default and refactoring if it becomes necessary to change the value. You will be forced to refactor as your script will break if you don’t. If you do it the other way around, it becomes optional to do the refactoring – which IME means that it will stop happening once the deadline moves closer.

    /Thomas

  4. MaxArt says:

    I personally always use const right away, because 90% of the times I’m using immutable values. I usually can determine if a variable is going to change or not as I type code.
    Those rare cases when I actually need to change a const in let are way less burdersome than changing almost every let in const because I want to take it easy.
    var is a thing of the past for me. A past that I still have to deal with, though 😀

  5. Sarah Drasner says:

    Hey Wes!
    Great post, as always- I think the key takeaway I got from listening to Kyle speak is (and he can totally correct me if I’m wrong here) was that a lot of people seem to think that you can’t reassign with const, but actually you can- in objects or arrays. So he warns to stay away from const because you might actually be confusing the person reading your code. (With a preamble that we spend the majority of our time with code maintaining and reading it, not writing it).

    I’m not sure what I think, personally- it seems like it would have to depend on the consensus of the team I’m working on because Kyle is right that most of our code is for communication. I do see most people defaulting to const with some deviation, though.

  6. Sarah Drasner says:

    Hey Wes!

    Great post, as always- I think the key takeaway I got from listening to Kyle speak is (and he can totally correct me if I’m wrong here) was due to the confusion that Mathias mentions in his article, a lot of people seem to think that const is all about immutability. Mathias does a great job of showing how the value can actually be changed, in objects or arrays.
    So Kyle warns to stay away from const because you might actually be confusing the person reading your code. With a preamble that we spend the majority of our time with code maintaining and reading it, not writing it.
    I’m not sure what I think, personally- it seems like it would have to depend on the consensus of the team I’m working on because Kyle is right that most of our code is for communication. I’ve found a lot of nice value using let for for loops where var’s scope seems counterintuitive, and let does what’s expected. I do see most people defaulting to const with some deviation, though. Enough that teams will create tests that force everyone to move to const.

  7. Dave says:

    > “Those rare cases when I actually need to change a const in let are way less burdersome than changing almost every let in const because I want to take it easy.”

    This. I might change a const to a let every 100 variables, where as changing a let to a const would happen 100 times for every 1 time it didn’t. Indexes variables are virtually the only time I use let.

  8. Steve Clay says:

    I don’t write much JS, but I feel like adding let was a mistake. The problems it solved seemed already mitigated by practices and tools, and it cost the community in new decision points while coding and debates like these.

    • Not a mistake at all! It’s always good to have a native of doing a task to substitute the practices and tools which were time consuming (though not much) for no reason.

      We had to use a function wrapper to trap different values of a loop variable on each iteration. While now, with ‘let’, we get a new binding on each loop iteration.

      Sometimes we were also confused by the unwanted variables that came out of an ‘if’ block (and were needed only locally in that ‘if’ block) and got hoisted in the enclosing scope. ‘let’ doesn’t let that confusion arise. As Kyle says you can always use ‘var’ when you want to share a variable with larger scopes (like when you need last value of a ‘for’ loop’s variable outside the loop).

      And there’re many more workarounds that ‘let’ solves natively.

  9. @sleepyfox says:

    Why not just stick to pure functions that return values?

    `console.log(((c) => c ? ‘some value’ : ‘some other value’)(0))`

    This avoids the need to use any intermediate variables, whether const or let, so makes the whole discussion moot.

  10. Cory House says:

    Simpson’s suggestion is both needlessly complicated and backward. Default to the common case, which is const. When you need to refactor to let, you’ll be forced to do so. And if you need var, think very carefully about why. It should be rare in ES6+ land. Easy.

    • Joel Colucci says:

      I believe const should be used to explicitly express a constant variable (eg setting or magic number etc).

      The use of constant variables informs fellow developers that this variable has been intentionally chosen to not change and signals caution around altering it.

      Defaulting to const for all variables loses the semantics/utility of constant variables.

      Other programming languages signal constant variables with naming conventions such as all caps. I’m excited for const because it adds explicitly to constants as well as actual checking by the compiler.

Leave a Reply

Your email address will not be published. Required fields are marked *