# How to declare JavaScript variables: a look at let, const, and var


With the old JavaScript, we had only one way to declare a variable, and that was with `var`, like `var x = 10`. It will create a variable called x and assign a value 10 to it. Now with modern ES6 JavaScript, we have 3 different ways to declare a variable: `let`, `const` and `var`. We will talk about `let` & `const` later. For now, let's focus on `var`.

### var

We already know how to declare a variable with `var`. Let us now refer to some code to understand `var` properly.

```JavaScript
var x = 20;

function foo() {
    var y = 10;
    console.log(x);
    console.log(y);
}

foo(); // will print 20 and 10
console.log(x); // will print 20
console.log(y); // will throw a reference error
```


Those who are familiar with C or C++ might understand why the output is like so. This is because `x` is in global scope and `y` is in the function foo’s scope. As function `foo` has access to the global scope, from the inside of the function we can access both `x` and `y`. Printing `x` also goes fine because as `x` is in global scope, we can access it from everywhere. Things go wrong when we try to access `y` from the global scope because `y` is limited to the function scope only.

Similar to C or C++ right? No. Let’s see why not.

```JavaScript
var x = 20;
function foo() {
    var y = 10;
    {
        var z = 30;
    }
    console.log(x);
    console.log(y);
    console.log(z);
}
foo();
```


What do you think the output of the code will be? If you think that there will be a reference error at the line `console.log(z)`, then you are correct from a C or C++ point of view. But with JavaScript, that’s not the case. The above code will print 20 10 30.

This is because in JavaScript with `var`, unlike in C and C++, we don’t have any block level scope. We have only global and function level scope. So `z` falls under function foo’s scope.

Now we have one more example:

```JavaScript
var x = 20;
var x = 30;
console.log(x); // this will print 30
```


In C or C++ if we declare a variable more than once in the same scope we get an error. But that’s not the case with `var` in JavaScript. In the above example, it just redefines `x` and assigns a value of 30.

Let’s consider the below code snippets:

```JavaScript
function foo() {
    x = 20;
    console.log(x);
}
foo();
console.log(x);
```


The above code will print 20 20. So what happens here? If you declare a variable anywhere without the `var` keyword it becomes a part of the global scope. It is accessible from both inside and outside of `foo`.

```JavaScript
'use strict'
function foo() {
    x = 20;
    console.log(x);
}
foo();
console.log(x);
```


In the above code, we are using strict mode. In strict mode, an `x = 20` kind of declaration is not allowed. It will throw a reference error. You have to declare a variable using `var`, `let` or `const`.

### let

Now it’s time to have a look at `let`. `let` is the new var in ES6 but with some differences.

```JavaScript
let x = 20;
function foo() {
    let y = 10;
    {
        let z = 30;
    }
    console.log(x);
    console.log(y);
    console.log(z);
}
foo();
```


Remember that in JavaScript, `var` doesn’t have any block-level scope? Now block level scopes are back with `let`. If you execute the above code you will get a reference error at the line `console.log(z)`. The variable `z` declared with `let` is now in a different block-level scope and is not accessible outside of this scope.

```JavaScript
let x = 10;
let x = 20; // will throw an error
```


Re-declaration of variables with `let` is not allowed.

```JavaScript
var x = 10;
let y = 20;
console.log(window.x); // 10
console.log(window.y); // undefined
```


Global variables declared globally with `var` are added to the `global` object, the `window` in case of browsers. Variables declared globally with let are not added to `window` (global object). Though they are accessible globally, it's like it’s there but you can’t see it.

```JavaScript
console.log(x); //undefined
console.log(y); //reference error
var x;
let y;
```


Unlike `var`, `let` variables are not initialised with undefined before their definitions are evaluated. If you try to access the variable before that you will encounter a reference error. This is also known as the temporal dead zone. In simple words, hoisting is only available with `var`, not with `let` & `const`.

### const

`const` stands for constant, it is very similar to `let`. The only differences are its value cannot be changed and it needs to be initialised where you are declaring it.

```JavaScript
const x = 20;
console.log(x); // will print 20
x = 30 // will throw an error
```


It’s not that in the case of `const` objects you can change the property of that object — it’s just that you can’t reassign a `const` variable.

```JavaScript
const obj = {firstName: "James", lastName: "Bond"}
console.log(obj); // will print the obj object
obj.firstName = "Ruskin";
console.log(obj); // will print the obj object, it has new firstName
obj = {firstName: "James", lastName: "Bond"}; // will throw an error
```


Also as mentioned earlier you have to initialise a `const` variable, you can’t keep it uninitialised.

```JavaScript
const x; // will throw an error
some other code;
```


That’s all for this article — see you later!

### Thank you for reading :)

