JavaScript - var, let, const

in #programming7 years ago (edited)



As you know, There was only var keyword for variable declaration before ES2015. but Modern JavaScript have introduced let and const keywords for it.
So let's figure out the differences between var and the others.

Function Scoped

JavaScript's var has slightly different scope than any other programming languages. and it's called Function Scope.

the following examples are all properly working JavaScript codes.

function a() {
  if (true) {
    var x = 10;
  }
  console.log(x); // prints 10
}

function b() {
  for (var i = 0; i < 10; i++) {
    var k = '99';
  }
  console.log(k); // prints '99' 
}

You may feel it's something strange. but above codes are all properly working codes becauseof Function Scope.

With Function Scope, All variable declarations inside function are all alive along with the function that variables was declared.

Hoisting

Here is one more strange rule which var has called Hoisting. (Personally, I couldn't understand why Hoisting was needed for JavaScript)

These examples are all properly working JavaScripts.

function a() {
  x = 10;
  console.log(x); // prints 10

  var x;
}

function b() {
  y = 100;

  if (false) {
    var y;    // even this code will not be evaluated, you can delcare a variable like this
  }

  console.log(y); // prints 100
}

Basically, JavaScript Parser parses the function and finds out all var variable declarations and moves it to the top of the function.
and this feature is called Hoisting.

So the above function b can be converted like this:

function b() {
  var y;
  y = 100;

  if (false) {
  }

  console.log(y);
}

and let

All those weird language features makes ES2015(ES6) to do introduce the let keyword.

let has following differences compare to var:

  • Block Scoped
  • Hoisting but with Temporal Dead Zone

Then, Let's figure out more about these differences.

Block Scoped

With let, the following examples are no more working like the examples with var.

function aa() {
  if (true) {
    let x = 10;
  }
  console.log(x); // a is not defined
}

function bb() {
  for (let i = 0; i < 10; i++) {
    let k = '99';
  }
  console.log(k); // k is not defined
}

because let is Block Scoped, variables using let will only be alive for the block ({ }) that variable was declared.

and I think this is more understandable rule than Function Scoped.

Temporal Dead Zone

let is still hoisted like var but the additional rule called Temporal Dead Zone has been added. So the following example is no more working with let variables.

function a() {
  x = 10;         // a is not defined
  console.log(x);

  let x;
}

In Temporal Dead Zone semantics, you can't access the variable which hasn't initialized. so a let variable declaration still be hoisted, but it works like its not hoisted.

I think simple hoisting only makes codes hard to maintain.
with let variables, Now you can make more easier to maintain JavaScript codes.

Then... What is const?

In Programming, all mutable variables can be considered as evil. because it changes program state and many mutable variables makes it impossible to track the state you are changing.

So Basically, we need to make variables immutable as possible. const keyword is needed for it.

It's like a let keyword, but when you assign the variable once, you can't re-assign the variable.

The actual value of the variable is not immutable, you can still change the properties of the value

function a() {
  const x = 10;

  x = 100; // Error!
}

like the above example, you can't re-assign the const variable. and const must be declared with initial assignment.

function b() {
  const y; // Error!
  y = 100;
}

You can use const keyword for variables that only needs one assignment. you can treat the const variables as immutable.

const keyword allows you to create more maintainable code. So I personally recommend to use it as many as possible.

Conclusion

  • var: Function Scoped, Hoisting
  • let: Block Scoped, Hoisting + Temporal Dead Zone
  • const: let + Immutable

References

Sort:  

Great post. Mutability in JS makes things very complicated (I recently had a hair pulling bug that modified properties on an unintended object). You know you can also create a constant object with Object.seal(obj) ? Once you pass your object to the seal method, you won't no longer be able to modify its properties.

I have a couple of javascript posts on promises as well...check them out and follow me @codero

Nice, promises can be pretty daunting for new developers. Good to see you're writing some explanations for those that need it. Followed :)

Thanks for the great tip, I will follow you, Thanks

OMG!
I didn't know that this would work:

function a() {
  var a = 5;
  if (true) {
    var a = 10;
  }
  console.log(a); // prints 10
}

Does it work same in NodeJS as well?
Usually I don't reuse variables in the same function, but it could mess up my code if I'm not careful!

Extremely valuable, thanks for sharing!

Right!, Thanks for the another cool example!

I remember the java script lesson I learned at university.

Haha, I learned JavaScript at the college too!

Taught myself Javascript.