Using ECMAScript 6 Today – Why wait? – Type of Features



Using ECMAScript 6 Today – Why wait? – Type of Features

0 0


es6-tech-taco-tuesday


On Github impatient / es6-tech-taco-tuesday

Using ECMAScript 6 Today

Why wait?

Scott Dillender (@smimp)

Interest in this after listening to some Javascript Jabber episodes on it Mention your version grunt traceur

Overview

  • Should you use it today?
  • What ES6 gives us
  • Clarity on spec status
  • Types of features
  • Quick run through of the new features
  • How the existing tools work
  • Where to learn more
Yes; Is it the wild west. Not really. Goal of the talk: Already loads of information out there. I aim to distill it and provide access to the better content. No object.observe. Proxies implemented differently. Older version of the spec Syntactic sugar vs actual new features. Comparison to Coffee script

What is ES6/Should you use it today

ES6 is the result of years long work by the TC39 standards body (Comprised of representatives from various tech companies)

Evergreen Browsers

We're finally to a point where all of the major browsers will be on a relatively frequent release cycle.

  • Firefox - 7 releases in the past year
  • Chrome - 8 releases in the past year
  • IE - last two major releases were in October of 2012 and 2013.

We have the technology

With features added in ES5, most of the features in ES6 can be implemented with a polyfill or with some clever code rewriting.

Tools that support this:
  • Traceur - Google
  • Regenerator/Recast - Facebook

Current Browser Share

ES5 Compatibility Chart

Summary of New Features

  • Arrow Functions
  • Classes
  • Generators/Iterators
  • Comprehensions/Spread/Destructure
  • Map/WeakMap/Set/WeakSet
  • Proxies
  • Numerous Utility Methods
  • Imports

Current Spec Discussion

  • Generator Comprehensions
  • ES6 modules
  • Object.observe - Definitely in ES7, but no one got the message
Generator comprehensions: concerns about parallelization (Perhaps automatic) Modules: what is the this. When doing modules, what is the equivalent of __dirname. module command, defaults Observe: Moved to ES7. People are already moving forward with implementation/use, which makes it somewhat risky, more in regard to divergent implementations

Type of Features

  • Syntactic Sugar

    If you're creative/masochistic, you may already have some of these. Of course, it's probably very verbose.

  • Features that are completely new and can't be replicated.

Rest Parameters - Syntactic Sugar

function rest(a, ...b) { console.log(a,b); };

function unrest(a,b) { console.log(a,b); }

function restEnd(primaryFunction) {
  return function() {
    var argSize = arguments.length;

    return primaryFunction.call(this,
        arguments[0],
        [].slice.call(arguments,1)
    );
  }
}

restEnd(unrest)(1,2,3,4);
rest(1,2,3,4);

Proxy - New Functionality

var a = Proxy({}, {
    get: function() { console.log("get arguments", arguments); },
    set: function(obj, prop, newVal) {
        console.log("Calling set with ", arguments); obj[prop] = newVal;    }
    });
a.eek = 'bam';

Returns: "Calling set with " Arguments
   {0: Object, 1: "eek", 2: "bam", 3: Object, 2 more…}

Generators - Borderline

var numberator = function*(base) {
  while(base < 4) {
    yield ++base;
  }
  return ++base;
};

//Array comprehension
var eek = [for ( x1 of numberator(-5)) if(x1%2 === 0 ) x1];
console.log(eek);
var numberator = $traceurRuntime.initGeneratorFunction(function $__22(base) {
return $traceurRuntime.createGeneratorInstance(function($ctx) {
  while (true)
    switch ($ctx.state) {
        case 0:
            $ctx.state = (base < 4) ? 1 : 5;
            break;
        case 1:
            $ctx.state = 2;
            return ++base;
        case 2:
            $ctx.maybeThrow();
            $ctx.state = 0;
            break;
        case 5:
            $ctx.returnValue = ++base;
            $ctx.state = -2;
            break;
        default:
            return $ctx.end();
            }
            }, $__22, this);
            });

ES6 in 3 Easy Slides

Frankenfunctions

The One With the Friends Reference?

The One With the Kitchen Sink

//arrow + destructuring + default params
var fibNext=({last=0,current})=>{ return last + current};
var gen = function *(...two ) { //generator + rest params
  var [last,current] = two;  //destructuring
  var next = fibNext({last,current}); //shorthand object syntax
  while(next < 1000) {
    next = fibNext({last,current});
    [last, current] = [current,next]; //destructuring
    yield next; //yield keyword (for generators)
  }
}
for(let z of gen(0,1)) { //generator + let
  var q = [ for (n of gen(...[0,1])) if (n=== z) n ]  //iterators + array comprehension + spread operator
  console.log(\`Runtime complexity ${q}\`); //string templating
}

export gen //modules

The One with the Long Distance Relationship

class HttpResolver { //class
  constructor({url, method, data}) {
    this._xmlHttpRequest = new XMLHttpRequest();    
    this._promise = new Promise(this.resolve.bind(this)); //context is important here es5
    this._xmlHttpRequest.open(method, url);
    this._xmlHttpRequest.send(data); 
  }
  getData() {
       return this._xmlHttpRequest.responseText;
  }
  resolve(resolve,reject) {

    this._xmlHttpRequest.onreadystatechange = () => { 
      if(this._xmlHttpRequest.readyState==4 && this._xmlHttpRequest.status==200) {
          resolve(this.getData());
      }
    }
    this._xmlHttpRequest.ontimeout = () => { throw new Error('timeout'); }
  }
  get promise() { return this._promise; } //get modifier (Use .promise instead of .promise() es5
}

Continued

class JSONResolver extends HttpResolver { //extends
  getData() {
   return JSON.parse(super.getData());
  }
}

var request = (options) => { //arrow function

  var {url, method, data, Resolver} = options;
  return new Resolver({url,method,data});//shorthand object creation

};

//thanks to openstreetmap for the easily accessible cors api.
var act = request({ 
   url: 'http://taginfo.openstreetmap.org/api/4/search/by_keyword?query=fire&page=1&rp=10',  
   method:'get', Resolver: HttpResolver });  
var act2 = request({ 
   url:'http://taginfo.openstreetmap.org/api/4/search/by_keyword?query=fire&page=1&rp=10', 
   method:'get', Resolver: JSONResolver });  

act.promise.then((data) => console.log(typeof data));
act2.promise.then((data) => console.log(typeof data));

The One Where Phoebe Forgets Something

   var wm = new WeakMap();
   var m = new Map();
   var s = new Set();
   (function() { 
     var c = {'not':'me'}; 
     m.set(c,{'o':'k'});
     wm.set(c,{'o':'k'});
     s.set(c);
     console.log(wm.get(c));
   }
   )()

   wm.has(m.keys().next().value); 
   s.has(m.keys().next().value);

  //ES6 Spec..an ECMAScript implementation must not provide any means to observe a key of a 
  //WeakMap that does not require the observer to present the observed key.

More Classes

class Parent {
  constructor(eek) {
  this.eek = eek;
  }
  height(h) {
    if(h) {
      this.h =h;}
    else {
      return this.h;
    }
  }
}
class Child extends Parent {
  constructor() {
    super(10);
  }
  height(h) {
    super.height(h);
    this.h2=h;
  }

  static defaultKid() {
    var toBe = new Child();
    toBe.height(32);
    toBe.name = 'Shakespeare';
    return toBe;
  }

}

Available tools - Traceur

  • grunt-traceur
  • gulp-traceur

Steps to use grunt-traceur

npm install grunt-traceur --save-dev Update your gruntfile Profit??
Will need to add watch as well and choose the destination of the js files. In addition, you should choose a module type. CommonJS and AMD(require) are also supported as well as an option that compiles everything into one file.

Questions?

  • Continued tomorrow at Afternoon Tea
  • Presenting at @midwestio in July