DEV Community

loading...
Cover image for Stop using var for declaring variables !!!

Stop using var for declaring variables !!!

mindninjax profile image Rishabh Singh ⚡ ・3 min read

Stop using var for declaring variables

If you are new to JS or been with it for quite some time then for the most part you probably be using var to declare your variables which is fine but it's not the most efficient & preferred way of declaring variables.

But why? And what should I use instead of var?

Let's find out!

Function Scope vs Block Scope

Block Scope

Most of the programming languages nowadays support a concept known as Block Scope, which means if a variable is declared within a block of let's say a for loop then that variable will not be accessible, outside that for loop.

If the variable of the same name is created outside the for loop then it will be treated as a different variable in the programming language which supports block scope.

Let's understand this through some pseudo-code:

function() {
    //This variable belongs to function scope
    name = "I am a string!"
    for {
        print(name)
    }
}
Enter fullscreen mode Exit fullscreen mode

Here we have a function with a for loop inside and a variable named name.

We are trying to read the variable in the for loop which is a child of the function.

When we run this command, we get this output:

I am a string!
Enter fullscreen mode Exit fullscreen mode

This indicates that we can successfully read variables present in the Function Scope.

Function scope is limited to the function itself. We cannot access the name variable from outside the function.

Let's try this one more time, but this time we will try to access the variable in the function from for loop.

function() {
    for {
        //This variable belongs to block scope
        name = "I am a string!"
    }
    print(name)
}
Enter fullscreen mode Exit fullscreen mode

When we run this code, we get an error that the variable is not declared i.e. variable doesn't exist.

This indicates that we cannot access variable present in the child block but the child block can access the variables present in the parent block.

This is known as block scope where the access of the variables is limited to that specific block only. Variables present in the function block can be easily accessed by the child blocks but the opposite is not true.

Let's talk about JavaScript now!

The block scope we just saw is applied in popular programming languages like Java & C++. Developers prefer using block scope as it helps them to make their code more efficient & less prone to errors.

Fortunately, with the release of ES6, JavaScript now supports Block Scope as well.

We can create block scope in JavaScript with the help of let & const keywords while declaring variables.

What are let & const?

let & const are JS keywords like var which can be used to create variables.

This is how we declare variables using var:

var name = "I am a var variable."
Enter fullscreen mode Exit fullscreen mode

However, variables created using var will be accessible throughout the function ie they will live in the function scope.

But as we just mentioned we want our variables to only be accessible within the block, it is created in.

To achieve this, we eliminate the use of var for declaring a variable and use let & const instead for variable declaration.

let name = "Bobby"
const birthday = "16 June"
Enter fullscreen mode Exit fullscreen mode

What's the difference between let & const?

  • let - Variables created using the let keyword can be easily modified and overwritten. You can use this keyword the same way you will use var
  • const - Variable created using const cannot be changed or modified. You can use this keyword for declaring a variable that is expected to remain constant throughout the execution so that it cannot be changed or modified by any means.

Final Takeaway!

Stop using var and start using let & const for variable declarations.

Support

Thank you so much for reading! I hope you found this blog post useful.

If you like my work please consider Buying me a Coffee so that I can bring more projects, more articles for you.

https://dev-to-uploads.s3.amazonaws.com/i/5irx7eny4412etlwnc64.png

Also if you have any questions or doubts feel free to contact me on Twitter, LinkedIn & GitHub. Or you can also post a comment/discussion & I will try my best to help you :D

Discussion (45)

pic
Editor guide
Collapse
ibrahimcesar profile image
Ibrahim Cesar

Using const only means that the variable will always have a reference to the same object or primitive value, because that reference can’t change. The reference itself is immutable, but the value held by the variable does not become immutable.

Collapse
mindninjax profile image
Rishabh Singh ⚡ Author

Hello Ibrahim, thanks for the explanation but it's probably too complex for our targeted audience, we will try to simplify your explanation and update our post accordingly.

Have a great day!

Collapse
larsonnn profile image
Lars Feldeisen

What target is that? the "I just learned to walk"? Constants are a basic concept of programming. And to point out that a Javascript const is not the same as a C const is not to hard.

Also you're completely right and I don't know why var still exist.

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt

For historical purposes, i.e. backward compatibility.

Thread Thread
larsonnn profile image
Lars Feldeisen • Edited

they could deprecate it. Like other stuff. It could be used but with a warning. In all MSDN docs you will find var declarations. That's not just about backward compatibility.

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt • Edited

Biggest major oddness about var, apart from hoisting and function scoped, is that you can declare it multiple times.

Thread Thread
larsonnn profile image
Lars Feldeisen • Edited

its because var is not realy declaring a variable like let or const, with var you adding something to this.

So this works:
var a = "a";
console.log(this.a); // 'a'

This not:
let a = "a";
console.log(this.a) // undefined

So every time you use var its like adding something to this. Thats the "function scope".

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt

It seems that var outperforms both let and const in 2017.

quora.com/What-is-the-performance-...

Thread Thread
larsonnn profile image
Lars Feldeisen • Edited

Thanks for sharing. Im gonna work it through and look if this still the case. 9 years difference (according to the engineer discussion)

Thread Thread
mindninjax profile image
Rishabh Singh ⚡ Author • Edited

Hey Lars! I will be replying to this comment of yours:

What target is that? the "I just learned to walk"? Constants are a basic concept of programming. And to point out that a Javascript const is not the same as a C const is not to hard.

Also you're completely right and I don't know why var still exist.

Alright, so our targeted audience is mostly comprised of people who are in their early stages of the coding journey and are just getting started, if you check our profile you will find most of the tutorial belong to that category only.

One of the main reasons we prefer to limit our audience is so that we can match the requirements of a beginner and make sure our explanation is understandable to them.

I hope this answers your question!

Have a great day!

Thread Thread
peerreynders profile image
peerreynders • Edited

Also you're completely right and I don't know why var still exist.

2021-Feb-25:

use var

Context:

try {
  const something = createSomething();
} finally {
  // ugghhhh just let me access `something` here
  something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

doesn't work because of the block scope const something is constrained to. var is scoped to the execution context so

try {
  var something = createSomething();
} finally {
  if (something) something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

will work. Otherwise one needs to resort to

let something;
try {
  something = createSomething();
} finally {
  if (something) something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

Just because you don't use it doesn't mean that it isn't useful.

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt • Edited

var add no real benefit over let in the case, and will break if I cover everything with ES6 block scope

Thread Thread
peerreynders profile image
peerreynders

Or is it that let doesn't add any real benefit in this case - and it is noisier as it requires a separate line of code just for the declaration.
And I don't understand what you mean with "will break if I cover everything with ES6 block scope".

Thread Thread
patarapolw profile image
Pacharapol Withayasakpunt • Edited

var can be scoped with IIFE, unless you expect scope leak.

let and const can be scoped with just {} alone.

One line of code doesn't matter that much (unless TypeScript - you need to and let type declaration).

I don't want to see this kind of bug.

fn(m)

// ... 10+ lines of code

try {
  var m = throwableFn()
} catch (e) {
  m.cleanup()
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
peerreynders profile image
peerreynders • Edited

If that is an issue, an entirely different conversation is necessary: Why is this type of code running in the Global Scope?

var is constrained (does not leak) within functions and within modules - so nothing about ES2015 or ESNext will make code that uses var "break".

I don't want to see this kind of bug.

  • How far in your process is f(m) going to get undetected given that m is going to be undefined?
  • How long are your functions that you may lose track that you already used m?
  • How descriptive is m anyway - likely two different names are more intention revealing.

In the majority of cases let and const are better - but that doesn't mean all cases.

Thread Thread
larsonnn profile image
Lars Feldeisen

they whole problem if the hoisting of var. Block Scope is safer in your daily programming. Why to I need to care of hoisting.?

try {
  var something = createSomething(); // something is now available in the whole function / global
} finally {
  if (something) something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

You only need to free resources when you doing something you don't wan't anything to access it later. The garbage collector will do the rest for you. So this example is shit. If you know how to program without side effects there is no real case you would go into this.

var could causing side effects if you don't carefully watch that you don't need it in the function. It has no benefit except you call hoisting one. So you want hoisting. And in my opinion (because that's all here) its shit.

Thread Thread
bryonmapes profile image
Bryon Mapes

I'm not personally a fan. I would rather use block scope with let.

Collapse
effinrich profile image
Rich Tillman

There's also "let", which I think sucks as well, but at least it's not var.

Collapse
gdledsan profile image
Mundo

There are still use cases to use var, are we going to see those too?

Collapse
mindninjax profile image
Rishabh Singh ⚡ Author

Thanks for the suggestion Mundo! Will send this to our editorial team!

And yes var hai its use cases but talking about ES6, using let and const are considered as best practices for modern web application development.

Have a great day Mundo!

Collapse
athomsfere profile image
Austin French

Although, I'd point out:

a const is a constant, and not a variable.

Collapse
bryonmapes profile image
Bryon Mapes

However:

"The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered."

Collapse
zuijin profile image
Trishiraj

How about we just throw JavaScript out of equation and glorify Jquery and it's sugar coated syntaxes!

Collapse
effinrich profile image
Rich Tillman

Haha, this headline is usually whisper yelled thru my teeth.

Collapse
chakudi profile image
Vaishali JS

Nice explanation of concepts, I really liked it.
The only thing I can't agree with is the title of the post. There is no point of avoiding var altogether if you understand its scope and impact.

Collapse
mindninjax profile image
Rishabh Singh ⚡ Author

Hey Vaishali!

We are very glad to hear that you liked our post :D

And yes we understand your concern regarding the title, I'll report it to my editor. But our main goal here is not to make judgemental titles, instead, we try to emphasize the overall takeaway of the post, we love people like you who always come forward and share their views and opinions about every single aspect of our work!

Thank you once again and have a really great day!

Collapse
chakudi profile image
Vaishali JS

Sorry for directly targetting the title but the only point I wanted to make is that though let and const are good addition to the language, var still holds its value and is still useful in many cases.

I love JS ♥️ and even though ES6 is booming, I still respect ES5 for its simplicity 👍

Thread Thread
lionelrowe profile image
lionel-rowe

Can you give an example where var is better? I've never come across one (unless targeting ES5 without transpilation for some reason).

Thread Thread
chakudi profile image
Vaishali JS • Edited

Did I say var is better? 🤔

Can you give example of an application which would be impossible to develop without let and const?

let and const are not essential features, they are just good to have things. With their introduction, var doesn't become obsolete. That was my point 😊

Thread Thread
lionelrowe profile image
lionel-rowe

You didn't say it's better overall, you said it's "useful in many cases". That's what I was asking for clarification about, because in my experience it's only useful as a transpilation target — when writing your own code, const and let always have better semantics and lead to fewer bugs. But I was curious as to what your counterexamples would be.

Thread Thread
chakudi profile image
Vaishali JS • Edited

There can be many examples. I can write an entire blog post about it 😅
There is a difference in the way JS engine treats var and let/const when it comes to initialisation process.

Also, I don't think either of these have better semantics, they just have different semantics.

And the amount of bugs have nothing to do with language features, in my experience. It depends on the developer's understanding of language.

Thread Thread
lionelrowe profile image
lionel-rowe • Edited
var strings = [
    'Sometimes,',
    '`var` is best,',
    'whereas other times,',
    '`let` is best.',
]

for (var [idx, str] of strings.entries()) {
    setTimeout(() => console.log(str), idx * 1000)
}
Enter fullscreen mode Exit fullscreen mode

😉

Thread Thread
chakudi profile image
Vaishali JS

Cute example, indeed!
But let only gives you a little bit more convenient way to handle this rare scenario.
You could certainly do it without let, if you are good at variables scopes, hoisting, execution context etc.

var devWhoKnowsHowToUseVar = (str) => {
  setTimeout(() => console.log(str), idx * 1000);
}

var strings = [
    'Sometimes,',
    '`var` is best,',
    'whereas other times,',
    '`let` is best.',
]

for (var [idx] of strings.entries()) {
    devWhoKnowsHowToUseVar(strings[idx]);
}
Enter fullscreen mode Exit fullscreen mode

Clearly, let is just a luxury but not necessity.

Getting back to my point: Though let is useful, we don't have to stop using var as it is useful in its own ways. Consider this small example:

if(user) {
  console.log('Welcome, ' + user);
} else {
  console.log('Welcome, guest');
}

let user = 'Vaishali'; // assume that user name received from API response
Enter fullscreen mode Exit fullscreen mode

The above will result in ReferenceError, but will work fine if let is replaced by var. There can be many more scenarios where var will be better suited as compared to the other options. After all, developers can choose to use either and get the things done without error, given that they know the language well.

My concern is not about var vs let, both are useful. I just wanna say that developers should use let and const wherever suitable, but there is no point of completely avoiding var as it has its importance in certain scenarios.

Thread Thread
peerreynders profile image
Thread Thread
peerreynders profile image
peerreynders • Edited

I think the original intent was :

function devWhoKnowsHowToUseVar([idx, str]) {
  setTimeout(() => console.log(str), idx * 1000);
}

var strings = [
  'Sometimes,',
  '`var` is best,',
  'whereas other times,',
  '`let` is best.',
];

for (var entry of strings.entries()) devWhoKnowsHowToUseVar(entry);
Enter fullscreen mode Exit fullscreen mode

i.e. while idx * 1000 "works" because it is used when devWhoKnowsHowToUseVar runs rather than when console.log is scheduled - having idx as an explicit parameter of the function is clearer.


The problem with "Stop using var for declaring variables !!!" - you need to be able to read code - so even if you yourself never use var, you still have to understand how it works to understand code from other sources.

Thread Thread
lionelrowe profile image
lionel-rowe
if(user) {
  console.log('Welcome, ' + user);
} // ...

let user = 'Vaishali';
Enter fullscreen mode Exit fullscreen mode

The way var is hoisted is yet another unnecessarily confusing thing about it. This would be easier to reason about if the declaration was written at the start and split from the assignment, which would work with let.

you still have to understand how it works to understand code from other sources.

Agree with this. JS devs should definitely learn about var so they can read legacy or transpiled code. Then they should (personal opinion) add a rule to their linter that disallows writing it in their own code.

Thread Thread
chakudi profile image
Vaishali JS

To be honest, this whole topic is about personal opinion/preference of developers with respect to variable declaration.

I've been working with JS for many years and 3 of my major projects are still completely powered by ES5, and believe me, I never had issues reading or understanding code with var.

In my personal opinion, let is only giving some convenience at lexical level which is certainly useful in many cases, but it doesn't replace var if you see from perspective of JS engine.

Thread Thread
peerreynders profile image
peerreynders

The way var is hoisted is yet another unnecessarily confusing thing about it.

It's only confusing if you're pretending to work (or rather be working) in "some other language". That is simply how var works in JavaScript - the "hoisting" is a natural consequence of var being function or globally scoped. For consistency sake, style guidelines recommended to put all var declarations at the top of the function and to resist the urge to pretend as if var was block scoped.

Then they should (personal opinion) add a rule to their linter that disallows writing it in their own code.

Acknowledging the "personal opinion" qualifier here, however:

  • Beginners need to know the rules and follow them.
  • Intermediates need to know and understand the reasoning behind the rules.
  • Experts will follow the rules implicitly because they understand their value and will accommodate everybody else by documenting clearly why the rule doesn't apply in this particular scenario (this in itself should serve as enough of a dis-incentive to discourage overriding the rules casually).

From that perspective a warning that can be disabled locally seems more appropriate.

Thread Thread
lionelrowe profile image
lionel-rowe • Edited

a warning that can be disabled locally seems more appropriate.

"A warning that can be disabled locally" is exactly how eslint (and I think all common alternatives) already work.

// eslint-disable-next-line no-var
var x = 5
Enter fullscreen mode Exit fullscreen mode

For consistency sake, style guidelines recommended to put all var declarations at the top of the function and to resist the urge to pretend as if var was block scoped.

Thus removing any perceived advantage from using var in the first place.

Thread Thread
peerreynders profile image
peerreynders • Edited

Thus removing any perceived advantage from using var in the first place.

I somehow doubt that "hoisting" was ever seen as an advantage of var - it's simply an emergent property of how var was implemented by the runtime - one that needs to be taken into account.

try {
  // eslint-disable-next-line no-var
  var something = createSomething();
} finally {
  if (something) something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

The obvious intent here is to cross the block scope barrier but in doing so something is now available in the entire function scope which shouldn't be construed as an invitation to use something before or after try/finally.

let something;
try {
  something = createSomething();
} finally {
  if (something) something.freeResources();
}
Enter fullscreen mode Exit fullscreen mode

Has the advantage of not being assignable before the let but still exists past the try/finally.


PS: Personally I'd likely go this route:

function useSomething(consumeSomething) {
  let something;
  try {
    something = createSomething();
    consumeSomething(something);
  } finally {
    if (something) something.freeResources();
  }
}

// ... 
try {
  useSomething(consumer);
} catch(error) {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

rendering the entire var vs. let discussion moot.

Thread Thread
larsonnn profile image
Lars Feldeisen

@Vaishali JS

And the amount of bugs have nothing to do with language features, in my experience. It depends on the developer's understanding of language.

What is that for a philosophy. Javascript has by far the most bugs writting I ever detected in any language. Because someone says you need to understand the language. No. You write an var at the end of the line is not understanding the language, is writing bad code.

Most of this because

  1. JS is often use in non critical projects
  2. you are not punished enough for errors because JS can run even if you get an error
    1. this is cool and shit
if(user) {
  console.log('Welcome, ' + user);
} else {
  console.log('Welcome, guest');
}

let user = 'Vaishali'; // assume that user name received from API response
Enter fullscreen mode Exit fullscreen mode

You done this? I hope not that is so fucking bad programming. Even when using var, declare it before you try to use it.

That's not an argument for var it's completely against it. Any developer watching your code needs first to be clear there is no var hidden in your function. And when you have big projects you don't want to do this. You want to have a clear view of functions. And don't want to read until the last line to be sure there was an var.

Thread Thread
peerreynders profile image
peerreynders

So this example is shit.

I didn't make it up - and crass language doesn't strengthen your argument.

I also don't believe hoisting of var was ever an actual, deliberate feature - it's simply an explanation (and name) of its behaviour given that it has function scope and can be declared anywhere within the function. Hoisting of function names on the other hand is quite deliberate because that way multiple functions can reference one another regardless of source order.

Javascript has by far the most bugs writting I ever detected in any language.

Are you talking about JavaScript or code written in JavaScript?

Lots of junior developers write code in JavaScript. Junior developers write "inexperienced" code in any language. And juniors not exploring other languages besides JavaScript probably have a hard time to improving their use of JavaScript.

JS is often use in non critical projects

It's also used in mission critical projects.
For example starting in 2014 eBay shifted from their Java-based stack to a Node.js-based stack - Marko which essentially runs their web front. - so what is your point?

you are not punished enough for errors because JS can run even if you get an error

Again forget about any expectations that you may have from some other language.
JavaScript's behaviour aligns with the web's resilience model. From the browser's point of view JavaScript is the least important aspect of any page it loads:

  1. Content is the foundation
  2. Markup is an enhancement
  3. Visual Design is an enhancement
  4. Interaction is an enhancement

JavaScript fails silently because the browser doesn't want to punish the end user for a developer's negligence of testing their code properly. This was in an attempt to preserve the information that could be conveyed by the content, markup and visual design.

It's client-side rendered SPA's which turned everything upside down. It's ironic that about the time the back end "discovered" microservices (2005-2011) the front end "discovered" monoliths in the form of SPA'a (2002-2003). Going by that MPAs should be coming back as the front end version of "microservices".

I'm personally not thrilled about Node.js being used in production on the back end - but it is. I'll also admit that JavaScript is far from the pit of success we would all like to have.

The problem with JavaScript is that it is deceptively easy to learn just a little bit of it; possibly operating on an erroneous mental model - but it actually takes quite a bit of effort to know JavaScript well enough to use it well.

Thread Thread
chakudi profile image
Vaishali JS • Edited

@larsonnn

What a vague comment is that!
I am myself using JS in a large missing critical project. We are a team of 20 JS develpers and we are using only ES5.

We have our own ways of achieving block scope using var and we have our own patterns for declaring globals!

Its definitely not about the language, its about the developers and the way they choose to use the language 😊

Thread Thread
larsonnn profile image
Lars Feldeisen • Edited

I was not answering you peerreynders
But here:

I didn't make it up - and crass language doesn't strengthen your argument.

I didn't say you did. The example is still a worst one. What you learn is, with var its not a problem if you code bad. And using var only that you can use it in finally or above your var statement is for me bad code. (Opinion here)

Are you talking about JavaScript or code written in JavaScript?

What's written in javascript ofc.

gain forget about any expectations that you may have from some other language.

You're right. That does not mean I need to accept the fact that var is for now. In my programs there is no var and I don't miss it. And I guess the most developers will not miss it if it's not available.

From the browser's point of view JavaScript is the least important aspect of any page it loads

in the 90s or early 00's yes. If you take v8 for example, it is clear that JavaScript is NOT the least important aspect. Also JS is one of the most used Languages. Or I didn't understand you here.

It's also used in mission critical projects.
For example starting in 2014 eBay shifted from their Java-based stack to a Node.js-based stack - Marko which essentially runs their web front. - so what is your point?

Ok fair. From the financial view. But do you wan't to run automated cars with javascript? Or Rockets to fly? Ofcourse not, it's fine. But that does not mean we should learn how to programm bad. And the language can support for writing easy safe code. And with node-js as your backend. I don't want some easy errors to make when it comes to writing Data in the Database. And we use so much microservices in JavaScript that we could raise the bar for what the language should have. If not, I don't see in the longrun JS only lose.

JavaScript is so quickly to mess up like no other language. And that's my whole point. Why sticking with var there is no use case. The only use cases presented was for hoisting. I don't see any other argument. Its not faster, its not saver. Its not intuitive to declare under the usage:

const fun= () => {
  if(true)
    var x = 2;
  console.log(x);

}
Enter fullscreen mode Exit fullscreen mode

Why should I do this? Its not intuitive. You would write more like this:

const fun = () => {
 let x; // or default value
 if(true) 
    x = 10;
 console.log(x);
}
Enter fullscreen mode Exit fullscreen mode

And that's just the worst example. Because you can write more elegant. But that's another topic.

I know that will not make JS the perfect language. And perfection will never be reached, because JS has many other things we could discuss.

Lots of junior developers write code in JavaScript. Junior developers write "inexperienced" code in any language. And juniors not exploring other languages besides JavaScript probably have a hard time to improving their use of JavaScript.

lots of junior developers write python or java code also. I see code from "experienced" developers which do the same misttakes. Or don't care and that's by far the worst.

It's client-side rendered SPA's which turned everything upside down. It's ironic that about the time the back end "discovered" microservices (2005-2011) the front end "discovered" monoliths in the form of SPA'a (2002-2003). Going by that MPAs should be coming back as the front end version of "microservices".

this will switch every time. That's normal. That's like haircuts. With nextjs or nuxtjs they just sell SSR as a new feature. (Yeah, it's a little more... But common).

[var, let] const is one statement to much.

Vaishali JS

Mar 7 • Edited on Mar 7
@larsonnn
What a vague comment is that!
I am myself using JS in a large missing critical project. We are a team of 20 JS develpers and we are using only ES5.
We have our own ways of achieving block scope using var and we have our own patterns for declaring globals!
Its definitely not about the language, its about the developers and the way they choose to use the language 😊

It's not about your project. And I don't care if you have 20000 JS developers. Its about the language. If you can't understand that the language can be better with more sense in it. I guess you live in your bubble.
Because you can use var and have 0 errors with it, does not mean its good to have var. And I don't care about ES5, it's old.

Thread Thread
chakudi profile image
Vaishali JS • Edited

No language is good or bad in its own. Its only the way developers understand and use it.

Edit:
Just to add, ES5 is certainly old but most developers are not relying on ES6 unless they have babel/webpack or other third party tools to transpile ES6 into something that browsers care about.