JavaScript Destructs
Tags: javascript
Published: 2017-07-14 09:46:57

---
title: JavaScript Destructs
published: true
description: Destructuring in JavaScript
tags: javascript
---

In this post I'm gonna talk about a feature that was added to JavaScript with ES2015: __Destructuring__

I'm also going to talk about features ES2015 added to the _initializer notation_ also known as object or array literals, which are the _other side_ of the story.

And I'm going into some features that aren't part of the ECMAScript standard (yet), but very high on the list of becoming one in the near future. Compilers like Babel already implementing them.

# Destructuring

Destructuring is a way to declare new variables based on objects or arrays, they can often eliminate the need of a few variable indirection's.

Lets start with a simple example.

    // Without destructuring you would write this:

    const someObject = {head: "ok", value: 11};
  
    if (someObject.head == "ok" && someObject.value > 10) doSomething();

    // With destructuring you could write it like that:

    const {head, value} = {head: "ok", value: 11};

    if (head == "ok" && value > 10) doSomething();

To add more sense to this, lets imagine you got `someObject` from a function:

    const {head, value} = getSomeObject();

    if (head == "ok" && value > 10) doSomething();

Or you get it as argument to a callback:

    function (otherArgument, someObject, anotherArgument) {

      const {head, value} = someObject;

      if (head == "ok" && value > 10) doSomething();

    }

Which can be simplified to:

    function (otherArgument, {head, value}, anotherArgument) {

      if (head == "ok" && value > 10) doSomething();

    }

Destructuring also allows you to _go deeper_:

    const { a: { b: { c } } } = { a: { b: { c: 10 } } };
    
    alert(c);

And, as I mentioned, it also works with arrays:

    const [firstElement, SecondElement] = [ 1, 2, 3 ];

    alert(firstElement + SecondElement);

And as argument:

    function ([first, second]) {

      return first + second;

    }

Swapping some elements without a proxy variable:

    const a = 1;
    const b = 2;
    
    [b, a] = [a, b];

As you see, when using arrays you are free to use any identifier you want, when using objects, you have to use the right property identifier.

Arrays destructuring also has a _rest_ syntax, which lets you extract some elements and create a new array with the remaining elements quickly.

    const [stringWithOne, ...arrayWithTwoAndThree] = ["one", "two", "three"];

There is even a rest syntax for objects, which aren't part of ECMAScript yet, but available via compilers like Babel.

    const {a, ...objWithBAndC} = {a: 10, b: 11, c: 12};

One nice thing about using it for function arguments is, you can use it with the default value feature. So you can extract the right values from an object or an array _and_ set default values for them in one stroke:

    // Before
    function parse(a) {
      const type = a.type || "default"
      ...
    }

    // After
    function parse({type = "default"}) {
      ...
    }

    // More complex
    function parse(a = 10, [first, second, ...rest], {b: {c: [deepFirst = 99]}}) {
      return rest.map(function(x) {
        return a * first * second * x + deepFirst;
      })
    }

There is also a rest syntax specifically for parameters, that can be used without objects or arrays. It works as an `arguments` replacement and is a _real_ array.

    function (a, b, ...otherArgs) {
      ...
    }

# Initializer Notation

The other side of this is the initializer notation, often also known as object literal syntax, which got a bit tweaked.

So you got your data extracted from somewhere and now you want to create a new object out of this.

     // Before
     const a = 10;
     const b = 11;
     
     const myObject = {a: a, b: b};

     // After
     const a = 10;
     const b = 11;
     
     const myObject = {a, b};

     // Like it worked with arrays before:
     const myArray = [a, b];

You can also use values of variables as names for your object inside the literal now:

     // Before
     const key = "hello";
     const value = "world";
    
     const newObject = {};
     newObject[key] = value;

     // After
     const key = "hello";
     const value = "world";
    
     const newObject = {
       [key]: value
     };

     // With some computation
     const newObject = {
       [getKey("some-ID") + "suffix"]: getValue("some-ID")
     }

There is also an inversion of the rest syntax for objects. The _spread_ operator, which isn't part of ECMAScript yet. It allows you to create new objects on the fly.

     const props = {size: 10, color: "red"};
     const newProps = {...props, color: "green", weight: 100};

With this you create objects based on other objects and can add properties (like `weight`), or override properties of the base object (like `color`).

But a bit of caution is advised. You get a new object, __but__ if you got some indirection's in the base object (nested objects) these won't get cloned.