Declaring JS Variables in 2019
Tags: javascript
Published: 2019-06-05 00:20:58

---
title: Declaring JS Variables in 2019
published: true
description: var, let or const: what is the right choice? 🤔
tags: javascript
series: Blog-A-Day in June
---

tl;dr my opinion 🤔💭: **use `const` by default**, only use `let` if required.

## History

JavaScript has three* ways to declare variables:

```js
var x = 123;
let y = 456;
const z = 789;
```

The first, `var`, comes from the original version of JavaScript. The later two arrived widely across browsers in about 2016.

## Constant by Default

If you declare variables with `const`, they cannot be changed ("mutated"). (If the variable points to an _object_, you can mutate the object.) For example:

```js
const value = 123;
const object = {abc: 123};

object.abc++;   // ok ✅
value++;        // error ❌
object = null;  // error ❌
```

This is an extremely primitive but useful method of safety while building JS. If a variable isn't meant to be mutated—it's the result of some complex operation—then `const` means you can't accidentally use it incorrectly. (This is also useful in conjunction with [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), where you can't just invent variable names without `var`, `let` or `const`). 🔬

## Let On Demand

If you later find out that you need a variable to mutate, you can go back to its declaration and mark it as `let`. This lets readers of your program know a bit more about the variable.

```js
const counter = getTotalEvents();

// ...later, we decide to add something, but this will 💥
counter += otherEvents();
```

If we modify `const counter` to be `let counter`, readers will know that it's not the final value: it will likely mutate further on below.

## Gotchas

* Function arguments are always mutable.

```js
function foo(foobar) {
  ++foobar;
  return foobar;
}
```

* You can and should use `const` inside a `for-of` or `for-in` loop (which is not always obvious, since it seems like the variable is mutating every iteration). 🤔

```js
for (const x in object) { ... }
for (const x of arrayOrIterable) { ... }
```

## Var Considered Confusing

Declaring with `var` has some quirks—the variable declaration is _hoisted_ to the top of a function, so it's always available. Here's an example, but showing that you could just use `let` instead:

![let vs var](https://thepracticaldev.s3.amazonaws.com/i/f9aaw9v8ojbt59z20s8f.gif)

Declaring with `var` can be useful in some occasions, but I believe it does not follow the [principle of least surprise](https://www.google.com/search?q=principle+of+least+surprise), and you can always replace it with `let`.

## The Exception*

Function declarations are technically another way to declare a variable.

```js
function foo() {
  // do stuff
}

// "foo" is now something we can pass around, e.g.:
setTimeout(foo, 1000);
```

This isn't _exactly_ like saying `var foo = function() { ... }`, but it's similar. The main difference being that the declaration itself is hoisted, not just the variable name. Here's that in action:

```js
foo();  // ok! ✅
bar();  // crashes: "bar" is a valid name, but contains undefined 😕

function foo() {}
var bar = function bar() {};
```

Function declarations _are_ a useful concept in JS, because it lets us pass around functions before they are declared—allowing for circular 🔄 references such as passing functions as callbacks. (If you're curious, I talk about how this interacts with ES6 modules in [a talk 🗣️💬 I gave at the Polymer Summit in 2017](https://www.youtube.com/watch?v=fIP4pjAqCtQ&list=PL5vCN4IjFTd40C6QRiHfs6h4MOdjbRo3B&index=14&t=0s)).

## Thanks!

That's all for today, just a simple opinion piece!

5 👋