DEV Community

John Wolfe
John Wolfe

Posted on • Edited on

Should You Truly Never Use var?

Some controversy in the Javascript community has emerged over this classic variable declaration. So, are the E6 purists correct and we should forever delegate var to the dustbin? This blog post will get to the bottom of the debate.

First, the arguments against var (the first two adopted from Learn Verified’s new and excellent V3 curriculum).

  1. No error is thrown if you declare the same variable twice using var (conversely, both let and const will throw an error if a variable is declared twice)

  2. Variables declared with var are not block scoped (although they are function scoped), while with let and const they are. This is important because what’s the point of block scoping if you’re not going to use it. So using var in this context would require a situation in which a variable declared inside a function would need to be used in the global scope. I’m not able to think of any situations where that would be absolutely necessary, but perhaps they exist.

  3. Another argument that has been made against the use of var is that JS Linters are now pointing out their use as bad practice. I conducted a quick search on the Internet that revealed Jslint.com and Jshint.com did not raise an issues with the use of var as a variable declaration. However, ESLint explicitly has a no-var rule aimed at discouraging the use of var.

  4. Most Javascript experts agree var shouldn’t be used. Douglas Crockford, the man who popularized JSON, is against the use of var. He indicates that, “var might possibly still be useful in an extreme case like machine-generated code, but I’m stretching hard there. Wes Bos also says he won’t use var.

So, with the above reasons clearly and logically indicating why var should never be used, why would anyone be temped to use it over const or let again? Kyle Simpson, author of You Don’t Know JS, and all-around Javascript guru, in this article, has argued for a possible case for var. Simpson argues that:

“There are going to be places in real world code where some variables are going to be properly scoped to the entire function, and for those variables, var is a better signal”

He provides this code block to illustrate his point:

Essentially, Simpson is arguing that while changing var with let in the above example will still work the same, because two blocks explicitly take advantage of let’s block scoping (remember only let/const are block scoped not var), var is a helpful signal to indicate a function scope.

(Simpson also makes the case that when he uses try…catch blocks for debugging, the Let block scope causes unwanted errors.)

Ultimately, after looking at this above example Simpson provides, it’s not difficult to see how var constitutes a cleaner option in that instance.
Of course, many people disagree with Simpson. Sure, in the above example var is a clearer signal than let, but since it operates the same, is it really worth bringing it into play?

Top comments (14)

Collapse
 
nektro profile image
Meghan (she/her)

For me, nope never again using var. it’s inefficient, hard to maintain, and error prone.

I don’t how unpopular this opinion is, but I think let and const should have been the only ways from the beginning. I know this isn’t the case because JavaScript was designed in about a week, but If we ever have a “JavaScript 2” then I would propose var being removed.

Collapse
 
johnwolfe820 profile image
John Wolfe

I think most people agree with you. Kyle Simpson's point about using it in top level variables that are shared across multiple scopes I think is legitimate, but even in that context its only advantage is to make the code more readable. It seems to me that selectively trying to use it in those situations would be error prone, like you mentioned.

I'm wondering if anyone has legitimate use cases where var remains the only viable variable declaration.

Collapse
 
nesvand profile image
Andrew Nesvadba

I don’t think there’s going to be a case where var is the “only viable” - all we’re left with is considering code style conventions like the one Simpson has suggested.

Will I adopt it personally? Probably not but it’s an interesting idea all the same.

Collapse
 
donut87 profile image
Christian Baer

If you have a variable in top-level shared across multiple scopes, then you have other things to worry about. Constants are fine btw. but variables? Things that can change? Over multiple scopes? Didn't we already discover this as a code smell?

Collapse
 
courier10pt profile image
Bob van Hoove

var - being function scoped - led to the 'habit' of declaring all variables at the top of the function. As long as you stuck to that, it would make bloated functions really stand out.

Lucky thing is you can use the same approach with let and it just works. I just hope the variables first approach will stay.

Thanks for writing the article.

Collapse
 
paulsmithkc profile image
Paul Smith

The "variables first approach" is an anti-pattern that originated in Fortran and continued with C, because compilers the time were not very smart and did not do a good job of optimizing code.

Putting all your variables at the top forces the compiler to allocate space for all of them on the stack from the beginning, even if you don't end up using them. It also prevents the compiler from intelligently warning you about uninitialized variables. That second point may seem small, but can be a deadly problem in medical software.

If you switch to use const to declare most of your variables when you need them there are several benefits:

  • Faster Code, because the compiler tends to put variables into registers instead of the stack
  • Less stack swapping because the compiler knows what variables are "live" and which ones have fallen out of scope
  • Better Readability, because your reader isn't hit with a wall of variables which may or may not be used later, but have an initial state which must be tracked and an unknown purpose.
  • By declaring the variables when you can actually initialize them and use them, the reader has a clear understanding of the purpose of the variables and doesn't have to track 10 variables that you might use later.
  • You don't accidentally use a variable that either hasn't been initialized or has been initialized to a non-sensical value. (Initializing to zero isn't always safe. A lot of people have died from programs where variables where erroneously initialized to zero.)
Collapse
 
alexdevmotion profile image
Alexandru Constantin • Edited

After reading your argument, I'm still sticking to my gut feeling of never using var

Collapse
 
denishowe profile image
Denis Howe

Does any language apart from JavaScript distinguish between function scope and other block scopes? Why should JavaScript retain a special keyword to make that distinction (other than as a memorial to historical implementation details)? Someone who is incapable of working out the scope of a let variable will probably not understand var either.

Collapse
 
sammyisa profile image
Sammy Israwi

I've tried to avoid using var ever since I learned about let and const. But since I watched Kyle Simpson's course on Frontend Masters (same argument as his article that you mentioned) I've been rethinking it.

Lately I've been using/experimenting again var unless I need to take advantage of block scoping.

Collapse
 
antonfrattaroli profile image
Anton Frattaroli

I started using let, stopped due to users experiencing issues on their iPads. Still too new. Certainly not introducing babel in an application for some nearly trivial differences in how code runs.

Collapse
 
sakex profile image
sakex

That’s why you should use Babel

Collapse
 
reegodev profile image
Matteo Rigon

If you wanna use es6 in your production code the only real choice is to use a compiler.
If you don't think setting up a compiler is worth then you don't really need es6

Collapse
 
johnwolfe820 profile image
John Wolfe

that's interesting, so you still have to use var?

Collapse
 
antonfrattaroli profile image
Anton Frattaroli • Edited

Yeah, not that I consider it a hardship. Safari on iOS <= 9.3 (2015-2016) doesn't support let.