JavaScript Scopes
Tags: javascript
Published: 2017-07-09 15:43:51

---
title: JavaScript Scopes
published: true
description: Scoping in JavaScript
tags: javascript
---

If you started working with JavaScript before the release of ES2015, you are probably used to the fact, that JavaScript variables are function-scoped and _hoisted_ etc.. With ES2015, you get a new way to define variables that are block-scoped.

# Before ES2015

Back in the days `var` was the keyword of choice to define a local variable, if you didn't use `var` and used a new indentifier for assignment, you could create a global variable, sometimes even by accident, if you didn't use the `"use strict";` statement.

```javascript
function () {
    // Global variable
    newIdentifier = 5;

    // Local variable
    var variable = 6;

    // Assignment to the defined variable
    variable = 8;

    // Another global variable (by accident)
    varialbe = 8; 
}
```

Your local variables were scoped by the function in which they were defined.

```javascript
// You could write something like this:
function (x) {
    if(x > 2) {
    var y = 10 * x
    }

    return y
}

// But behind the scenes it would be treated as this:
function (x) {
    var y
    if(x > 2) {
    y = 10 * x
    }

    return y
}
```

This lead many developers to define all the local variables at the top of the function, because they would end up there anyway.

# Since ES2015

With the release of ES2015 JavaScript got many new features, one of them _block scoped variables_. There are two kind of them, `let` and `const` variables.
    
```javascript
// So this wouldn't work:
function (x) {
    if(x > 2) {
    let y = 10 * x
    }

    return y
}
```

In the example, `y` is only accessible inside the if-block, which is the default behavior of many other languages.

What this allows you to do is define variables where they are needed and scope them with code blocks.

```javascript
// Every time you see a { and } you're creating a new block
// and in there you can create a new variable scoped to that block
while(...) {
    let x = 10;
}

for(...) {
    let x = 12;
}

if (...) {
    let x = 9;
} else {
    let x = 8;
}

try {
    let x = 1;
} catch (e) {
    let x = 99;
}
```

You can even use `{}` on their own for scoping, to keep the vars as local as possible.

```javascript
function () {
    let varForTheWholeFunction = 10;

    {
    let scopedVar = getData();
    varForTheWholeFunction = parse(scopedVar);
    }
    // scopedVar isn't accessible here
    ...
    {
    let scopedVar = filterData(varForTheWholeFunction);
    varForTheWholeFunction = sortData(scopedVar);
    }

    return varForTheWholeFunction;
}
```

This can be used for `switch` statements too.

```javascript 
function () {
    let a;

    switch(x) {
    case "getData": {
        let y = getData();
        a = parse(y);
    } break;
    ...
    default: {
        let y = "defaultData";
        a = parse(y);
    }
    }

    return a;
}
```

So what about `const`? Well, their scoping works like with `let`, but a value has to be assigned at definition time _and_ it can't change later, only if the function, in which this local variable is declared, is called again.

```javascript
function (x) {
    if (x > 2) {
    // This will fail:
    const a;

    // This will also fail:
    const a = 1;
    a = 2;
    }
}
```

So it's a variable that can only be set once, but be careful:

```javascript
function () {
    // This would work:
    const x = {y: 1};
    x.y = 2;
}
```

Indirections aren't save from mutation.

# Conclusion

With `let` and `const` JavaScript got a way to define scopes more fine granular, which enables developers to limit code dependencies even more. 

The cost of this is added complexity to the language, but on the other hand, you don't have to use all of the features that exist :)