# Declaring variables in ECMAScript 2015

Source: https://tpiros.dev/blog/declaring-variables-in-ecmascript-2015

ES2015 (ES6) is an alias for the latest version of the JavaScript programming language. Like any other programming language, JavaScript has versions. Most of the JavaScript out there has been written using ES5 or ES5.1. (Or even ES3.)

ES stands for ECMAScript. It refers to a specification standardised by Ecma International, a standards organisation. They're responsible for other standards too, like the JSON standard.

The latest, fully released version of JavaScript at the time of writing is ES2015, and it brings some brilliant additions to the language.

## Using `var`

For the past decade, defining variables in JavaScript meant using the `var` keyword. Variable declarations happen before any code runs. That process is called variable hoisting. (In fact, all declarations get processed before code execution, including function declarations.)

The following code works in JavaScript (without strict mode):

```javascript
name = 'Luke Skywalker';
var name;
```

Because hoisting effectively turns it into:

```javascript
var name;
name = 'Luke Skywalker';
```

Hoisting produces a lot of implications (sometimes nasty ones). Thankfully, ES2015 gives us a solution: the `let` and `const` keywords bring block-scoped variables to JavaScript.

> `use strict`
>
> Strict mode lets developers write better code by tightening the "forgiveness" of the language. To invoke strict mode, include the `use strict;` statement in your code, applied either to the entire file or to individual functions. It eliminates silent errors, forces JavaScript to actually throw error messages (like using a variable before declaring it), and prevents variables from leaking onto the global scope.

Since we're writing ES2015 code, my preference is to drop `var` entirely and use `let` and `const` instead. But you might be wondering: are there differences between `let` and `const`? Yes. Let's look at them.

## let vs const

Let's start with what `let` and `const` share.

Both are block-scoped. If they're declared inside a block (like an `if` statement or a function), the variable and its value are only accessible inside that block.

That's not how `var` behaves. Here's an example:

```javascript
if (1 === 1) {
  let name = 'Luke Skywalker';
}
console.log(name); // ReferenceError
```

The `name` variable can only be reached inside the block. Swap that declaration to `var` and you'll see completely different behaviour.

The `const` keyword works a bit differently from `let`. As the name suggests, `const` is for declaring constant variables, variables whose references won't change. Keep in mind though: `const` doesn't make variables immutable.

> Mutable vs Immutable
>
> Mutable and immutable are key concepts in computer science, most often mentioned alongside objects. Mutable simply means changeable; immutable means unchangeable. If an object can be modified after creation, it's mutable. In JavaScript, custom objects (objects created by you) are mutable, but some built-in types (like Number) are immutable.
>
> If you want to make your object immutable, you can use `Object.freeze()`.

> Arrays and Objects
>
> Arrays are data structures that hold information. They're similar to a list and can store strings, numbers, booleans and objects (don't forget, a function is also an object in JavaScript).
>
> Objects are similar to real-life "objects" like a car. A car has properties with values: for example, it can be a red car. Those properties define the characteristics of the object.

Another significant difference between `let` and `const`: you can't reassign a variable declared with `const`. Here's an example:

```javascript
const name = 'Luke Skywalker';
name = 'Darth Vader'; // TypeError: Assignment to constant variable.
```

But when working with objects, you can still add properties even when you've declared the object with `const`. That's because we're not reassigning the `const` variable itself. We're modifying what it references. (To freeze an object created via `const`, call `Object.freeze()` on it):

```javascript
const characters = { rebels: ['Luke', 'Han'] };
characters.rebels.push('Lando');
console.log(characters); // { rebels: [ 'Luke', 'Han', 'Lando' ] }
```
