Last update on Sunday, November 6th 2016

ES6 Features That Can’t Be Ignored (final part)

Hi folks,
Second and last part of the ES6 tuts.
Here we will have a look at the Generators, the new Promise object, how to destructure to realise fancy assignments, how the anonymous functions evolved and finally a sneak peek into the Symbols. Let's get our hands dirty!

Generators

One of the coolest features that ES6 brings is the Generator. Now you can say **** you to the asynchronous aspect of JavaScript.

By creating a Generator function using the '_' character, you can pause the execution of a method at a 'yield' keyword. To resume the execution of the method, you need to grab the returned generator and call the method named next.

Here is an example where I yield the method at an asynchronous action then unpause it once I got the awaited result:

function getIdInDb() {
  // Simulate async Db request
  setTimeout(function() {
    tmp.next(2); // I return 2 as a result for my Id
  }, 2000);
}

// Use the id returned by the yielded function
function getUserWithId(id) {
  console.log("Getting user with id:", id);
}

function* doSomethingInTheDb() {
  let id = yield getIdInDb();
  console.log("The id is:", id);
  getUserWithId(id);
}

// Stock the generator
var tmp = doSomethingInTheDb();

// Trigger the first yield
tmp.next();

Promises

No need to use $q or whatever 3rd party library anymore. Now you can just use a Pure JavaScript Promise like this:

var promise = new Promise((resolve, reject) => {
  resolve("success");
});

function handleSuccess(result) {
  console.log("success", result);
}

function handleError(err) {
  console.log("error", err);
}

promise.then(handleSuccess, handleError);

Destructuring

Destructuring is quite a touchy part of ES6 because it can make or break a developer. The major change of philosophy here is to accept that there might be some holes in the signatures, we generally try to fill those holes using null or undefined, so here the greatest challenge is to lose this "perfectionism".
Here are some examples with an incremental difficulty:

const [a, b, c] = [1, 2, 3];
console.log(b); // 2

const [d, , f] = [4, 5, 6];
console.log(f); // 6

const { id, surname, name } = { age: 26, name: "Matthieu" };
console.log(name); // Only name is defined so: Matthieu

const { test = "Default value" } = {};
console.log(test);
// Default value

const { address } = { address: { street: "Here", city: "There" } };
console.log(address);
// Object {street: "Here", city: "There"}

You can also couple it with the shorthand examples from the previous post.

Anonymous functions

A very quick one here, if you are just like me and don't like the syntax for anonymous functions, you can replace it by simply using {} instead of (function () {})(); Just like this:

function sayHi() {
  console.log("hi 1");
}
{
  function sayHi() {
    console.log("hi 2");
  }
}
sayHi();

Symbols

Another controversial feature here: the Symbols.
Just like many people, I think that there is something missing in this feature.
This feature was stolen created in order to prevent name clashing when manipulating objects.

An example of name clashing looks like this.
Someone access the object foo and use the key bar. Just after that you do the same and overwrite this property. That's quite annoying right? And this is because the key is a String.
A symbol is very helpful in this case. A symbol is not private but it is collision free. Name clashing using Symbols is like burning down your house with a flamethrower then saying that you only forgot to put out a candle before sleeping.

Here is an example showing how to use Symbols to prevent collisions.
By keeping the symbol inside of the object we can limit the public manipulation of a property:

var Person = (function() {
  var ageSymbol = Symbol("age");
  function Person(age) {
    this[ageSymbol] = age;
  }
  Person.prototype.getAge = function() {
    return this[ageSymbol];
  };
  return Person;
})();

var a = new Person(26);
console.log(a.getAge()); //Output: 26
a.age = null;
console.log(a.getAge()); //Output: 26

Nice isn't it?
Unfortunately, it's not perfect. Mainly because it's not private. You can literally grab a symbol whenever you want, wherever you want:

let obj = {};

var symb = Symbol.for("Symbol");
obj[symb] = "supposed to be hidden";
console.log(obj[symb]); // 'supposed to be hidden'

var sameSymb = Symbol.for("Symbol");
console.log(symb === sameSymb); //true
kids-skeptical-es6-symbol Since you can grab the symbol from anywhere, you can overwrite the data whenever you want, just like this:
obj[sameSymb] = "Your data just got overwitten";
console.log(obj[symb]); //Your data just got overwitten

Conclusion

We have seen here some powerful tools like Generators and Desctructuring Assignement that transform the way that we code nowadays and in the future. Moreover, some features like Async in ES7 are inspired by features from ES6 (Generators in this case), hence those new principles will be propagated in the future implementations of JavaScript.
Some are good to know, like Vanilla JavaScript Promises and some are literally ignored like Symbols.

ES6 Features That Can't Be Ignored (part 1)

Introduction to Ionic Google Analytics

Analyzing the Ionic AWS Full-Stack Starter: Custom APIs

Stay up to date


Join over 4000 other developers who already receive my tutorials and their source code out of the oven + other free stuff!