Six More Tiny But Awesome ES6 Features

By  on  

ES6 has brought JavaScript developers a huge new set of features and syntax updates to be excited about.  Some of those language updates are quite large but some of them are small updates you would miss if you weren't careful -- that's why I wrote about Six Tiny But Awesome ES6 Features, a list of the little things that can make a big difference when you code for today's browsers.  I wanted to share with you six more gems that you can start using to reduce code and maximize efficiency.

1.  Object Shorthand

A new object creation shorthand syntax allows developers to create key => value objects without defining the key: the var name becomes the key and the var's value becomes the new object's value:

var x = 12;
var y = 'Yes!';
var z = { one: '1', two: '2' };

// The old way:
var obj = {
    x: x,
    y: y,
    z: z
};

var obj = { x, y, z };
/*
    {
        x: 12,
        y: "Yes!",
        z: { one: '1', two: '2' }
    }
*/

I can't tell you the number of times I've manually coded key => value properties in this exact same way -- now we simply have a shorter method of completing that task.

2.  Method Properties

When it comes to these ES6 tips, it seems like I obsess over just avoiding adding the function keyword...and I guess this tip is no different.  In any case, we can shorten object function declarations a la:

// Format: { myFn(param1) { ... } }
var davidwalsh = {
    makeItHappen(param) {
        /* do stuff */
    }
}

You have to admit that leaving off all of the function keyword madness does make for cleaner code and less maintenance.

3.  Blocks vs. Immediately Executed Functions

The pattern for creating immediately executing functions is a bit ugly:

(function() {

   /* do stuff */

})();

With ES6 we can create a block with just {}, and with let, we can accomplish immediately executing function-like behavior without all the parens:

{ 
    let j = 12; 
    let divs = document.querySelectorAll('div');

    /* do more stuff */
}

j;  // ReferenceError: j is not defined...

If you declare a function within the block, it will leak out, but if you keep to let, you've essentially created an IEF without the parens.

4.  for loops and let

Because of variable hoisting within JavaScript, oftentimes we would either declare "useless" iterator variables at the top of blocks, code for(var x =..., or worst of all forget to do either of those and thus leak a global...just to iterate through a damn iterable.  ES6 fixes this annoyance, allowing us to use let as the cure:

for(let x = 0; x <= elements.length; x++) {
  console.log(x); // x increments
}

x; // ReferenceError: x is not defined

In the near future we'll see let being used as much if not more than var.

5.  get and set for Classes

As a member of the MooTools team, I was a huge fan of classes in JavaScript before JavaScript classes were really a thing. Now they're a thing:

class Cart {
  constructor(total) {
      this._total = total;
  }
  get total() { return this._total; }
  set total(v) { this._total = Number(v); }

  get totalWithTax() { return parseInt(this._total * 1.1, 10); } /* 10% tax */
}

var cart = new Cart(100);

cart.totalWithTax === 110;

The best part is the new ability to create getters and setters for properties! No need to create special setting via functions -- these automatically execute when they're set via basic obj.prop = {value}.

6. startsWith, endsWith, and includes

We've been coding our own basic String functions for way too long -- I remember doing so in the early MooTools days.  The startsWith, endsWith, and includes String functions are examples of such functions:

"MooTools".startsWith("Moo"); // true;
"MooTools".startsWith("moo"); // false;

"MooTools".endsWith("Tools"); // true;

"MooTools".includes("oo"); // true;

Seeing comon sense functions make their way to a language is incredibly satisfying;

ES6 has been an incredible leap forward for JavaScript. The tips I've pointed out in this post and the previoius go to show that even the smallest of ES6 updates can make a big difference for maintainability. I can't wait to see what the next round of JavaScript updates provides us!

Recent Features

  • By
    Write Simple, Elegant and Maintainable Media Queries with Sass

    I spent a few months experimenting with different approaches for writing simple, elegant and maintainable media queries with Sass. Each solution had something that I really liked, but I couldn't find one that covered everything I needed to do, so I ventured into creating my...

  • By
    Serving Fonts from CDN

    For maximum performance, we all know we must put our assets on CDN (another domain).  Along with those assets are custom web fonts.  Unfortunately custom web fonts via CDN (or any cross-domain font request) don't work in Firefox or Internet Explorer (correctly so, by spec) though...

Incredible Demos

  • By
    CSS Custom Cursors

    Remember the Web 1.0 days where you had to customize your site in every way possible?  You abused the scrollbars in Internet Explorer, of course, but the most popular external service I can remember was CometCursor.  CometCursor let you create and use loads of custom cursors for...

  • By
    MooTools-Like Element Creation in jQuery

    I really dislike jQuery's element creation syntax. It's basically the same as typing out HTML but within a JavaScript string...ugly! Luckily Basil Goldman has created a jQuery plugin that allows you to create elements using MooTools-like syntax. Standard jQuery Element Creation Looks exactly like writing out...

Discussion

  1. Carolina

    Thank you for the great article, David!

  2. Your fifth example seems broken and could be improved with Symbol:

    const totalSymbol = Symbol('total'); // Create a Symbol for the "private" key
    class Cart {
      constructor(total) {
          this.total = total; // Use the setter here ;)
      }
      get total() { return this[totalSymbol] || 0; } // Default to 0
      set total(v) { this[totalSymbol] = Number(v); }
    
      get totalWithTax() { return this.total * 1.1; } /* 10% tax */
    }
    
    var cart = new Cart(100);
    cart.totalWithTax === 110;
    
    // You cannot change cart._total anymore (and thus, break your getter and setters behaviour)
    // cart[totalSymbol] will work only with the totalSymbol reference
    // cart[Symbol('total')] won't since it is a new Symbol
    
  3. Your first code snippet under #3 is missing a closing paren. Probably a testament to how ugly that pattern is. :)

  4. Syntactically, object shorthands are the best features of ES6.

    It should be noted that ES7 (ECMAScript 2016) introduces includes API for arrays:

       [1, 2, 3].includes(2);
    
  5. Varunan
    "MooTools".startsWith(""); // returns true ??
    
  6. In my ES2015 experience for…of is even more common than the C-style for loops. If what I’m looping over isn’t already iterable, I’m likely doing something wrong. Bonus too, for…of loops don’t require any mutable variables. The iterator value can be declared as const, e.g. for(const item of items) { … }.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!