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).
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)
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.
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.
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)
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.
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.
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.
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?
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.
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:
After reading your argument, I'm still sticking to my gut feeling of never using
var
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.
I've tried to avoid using
var
ever since I learned aboutlet
andconst
. 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.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.
That’s why you should use Babel
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
that's interesting, so you still have to use var?
Yeah, not that I consider it a hardship. Safari on iOS <= 9.3 (2015-2016) doesn't support let.