DailyJS

DailyJS

The JavaScript blog.


TagES6
Featured

ES6 announcements

Standard ECMA-262, 6th edition (June 2015)

Posted on .

ECMAScript 6 has been finalised under Standard ECMA-262 6th edition (June 2015). There's no going back now! The JavaScript community can breathe a sigh of relief before gearing up for the next major language revision. Or will we all live in the future using transpilers? Let's take a minute to look at ECMAScript 2015's language features.

Declarations

JavaScript's scoping rules are difficult to understand because var behaves inconsistently depending on scope. The new keywords, let (MDN) and const (MDN), scope based on lexical environment:

Usually a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a BlockStatement, or a Catch clause of a TryStatement and a new Lexical Environment is created each time such code is evaluated.

So, not only do you get the extra expressive power of being able to declare constants, but you also get the ability to declare variables according to more natural scoping rules. Basically: let works the way most of us thought var did at some point when we learned JavaScript.

Here's something you can try in a Chrome debugger to see how this works:

(function() {
  'use strict'
  for (let i = 0; i < 3; i++) {
    console.log('loop:', i);
  }
  console.log('after loop:', typeof i);
})();

The last statement will show that i is undefined after the loop. Now try this:

(function() {
  'use strict'
  for (var i = 0; i < 3; i++) {
    console.log('loop:', i);
  }
  console.log('after loop:', typeof i);
})();

You should see that i still exists after the loop. Almost everyone I've ever explained this to has forgotten it within a week. The new wisdom is this: you probably want const! If not let. Let's forget about var and everything will be OK.

Arrow Functions

If you think it's weird that for doesn't exist in the same dimension as var, then what about this in anonymous methods? It's very easy to make the mistake of passing a function to a method and assuming this will be bound to the object that owns the method. What really happens is this becomes the global object.

Arrow functions (MDN) help avoid unbound weirdo global this and also makes anonymous functions more readable:

setTimeout(() => { console.log('Hello'); }, 1000);  

Arrow functions may omit the curly braces when arguments are supplied. Too many callbacks? Do I care when I can just type =>?

Generators

Generator functions (MDN) are ideal for creating functions that should be exited and continued later. They can make asynchronous APIs arguably cleaner, and are starting to be adopted by API designers for things that would be typically callback heavy, like database APIs.

Generator objects are both iterator and iterable: there's a whole section in the spec on iteration, but rather than puzzling over that if you want a solid technical introduction to iteration see Dr. Axel Rauschmayer's Iterables and iterators in ECMAScript 6.

Class syntax

Now you can make classes (MDN) the way you do in other languages. Kind of. Classes support subclassing (extend), and in derived classes you have to call super. Did you know that underneath the minimalist sheen of ES6 classes you'll find good old fashioned prototype chains?

The design of ES6 classes is mostly backwards compatible with existing code, so you don't need to rush around rewriting prototype classes as ES6 classes. However, like arrow functions and the new block scoping, using ES6 classes reduces boilerplate. You'll appreciate that fact when subclassing (there's no goofy constructor function .call, just call super).

Default and Rest Parameters

Speaking of boilerplate, did you know ES6 has default parameters (MDN) and rest (MDN) parameters?

You can now set defaults when defining arguments:

function f(a, b=123, c='a') { console.log(a, b, c); }  
f('a!');  

And here's a "rest" example:

function multiply(multiplier, ...theArgs) {  
  return theArgs.map(function (element) {
    return multiplier * element;
  });
}

var arr = multiply(2, 1, 2, 3);  
console.log(arr); // [2, 4, 6]  

More

Naturally there's a lot more that I don't have time to cover today: maps, weak maps, destructuring, modules, promises, proxies, typed arrays, template strings.

But of course, we're all using promises already! Template strings: grown up interpolation, extremely useful for everything from SQL statements to generating client-side HTML fragments.

Typed arrays relate to JavaScript evolving as a language for dealing with binary data: people have already been using and abusing them for making things like games, synthesisers, and graphics processing.

I saw this great tweet by Eric Elliott (retweeted by Marc Harter, my coauthor on Node.js in Practice) that linked the ES6 announcement with the news about WebAssembly:

WebAssembly, "wasm" for short, .wasm filename suffix, a new binary syntax for low-level safe code, initially co-expressive with asm.js, but in the long run able to diverge from JS's semantics, in order to best serve as common object-level format for multiple source-level programming languages.

It almost feels like JavaScript has changed overnight, except for the fact that ECMAScript 2015 has taken many years of hard work! It could have been more radical, but the standardisation process has kept it largely conservative and backwards compatible. It should also help us solve some of the issues JavaScript has as a language.

Now, if only those Node/io.js guys could get things all merged up so we can start using more ES6 features without having to transpile Node code...

Featured

ui react ES6 libraries

FluxThis Router, React Transitive Number

Posted on .

FluxThis ES6 Router

Josh Horwitz wrote in to say that FluxThis has a new router that takes advantage of ES6 syntax. It has an API that is inspired by Koa for defining routes with middleware that drops through a stack using the yield statement:

export default function (router) {  
  router.use(function *(next) {
    // do some stuff
    yield *next;
    // do some stuff after everyone else
  });

  router.all('/user*', function *userAuthHandler(next) {
    document.title = 'User Profile';

    // perhaps do some authentication stuff?
    if (authFails()) {
      this.rewriteTo('/notAuthorized);
      return; // short circuit the middleware chain
    }

    yield *next;
  });
}

The idea is to use middleware without using deeply nested callbacks, which the generator syntax seems to solve quite nicely.

FluxThis is a Flux implementation by the developers at AddThis.

react-transitive-number

react-transitive-number (GitHub: Lapple/react-transitive-number, License: MIT, npm: react-transitive-number) by Aziz Yuldoshev is a React component that transforms numbers into stateful counters with animations. The author has a demo that compares plain HTML with the TransitiveNumber version.

To use it, just wrap a number with a <TransitiveNumber> component. The animation looks like a tumbler from an old clock, and apparently it was inspired by Groupon's old countdown timers.

Featured

database ORM iojs frameworks ES6 node express

Node Roundup: io.js 2.2.1, firenze.js, Express Happiness

Posted on .

io.js 2.2.1

io.js 2.2.1 has been released. The notable change in this release is the switch back to this.client in the IncomingMessage constructor in the http core module. The original change broke compatibility with request, which is used by npm. The io.js contributors found out about it by running make test-npm. There's an interesting discussion about it in the io.js pull requests.

firenze.js

Fahad Ibnay Heylaal sent in firenze.js (GitHub: fahad19/firenze, License: MIT, npm: firenze), an ORM for SQL written in ES6. It's built with Babel so it should work with Node 0.10.x and 0.12.x.

The API is promise based:

var posts = new Posts();  
posts.find('first', {  
  conditions: { id: 1 }
}).then(function(post) {
  var title = post.get('title');
  var postObject = post.toObject();
  var title = postObject.title;
});

To define a schema, you first describe a collection (table) and then a model:

var Posts = db.createCollectionClass({  
  table: 'posts',
  modelClass: function () {
    return Post;
  }
});

var Post = db.createModelClass({ // or db.Model()  
  alias: 'Post',
  collectionClass: Posts,
  schema: {
    id: { type: 'integer' },
    title: { type: 'string' },
    body: { type: 'text' }
  }
});

But you can also use cool ES6 syntax like this:

class Post extends f.Model {  
  constructor(attributes = {}, extend = {}) {
    super(attributes, extend);
  }
}

The project has a lot more methods for querying and saving data -- take a look at the project's homepage to see the full documentation.

Express Happiness

Express Happiness (GitHub: andreas-trad/express-happiness, License: WTFPL, npm: express-happiness) by Andreas Trantidis is a framework built on Express that offers the following features:

  • A JSON route tree
  • Strictly defined, centralised error handling
  • Route permissions
  • Parameter validation
  • Automatic REST API documentation generation
  • Data mocking

Validation is automatic, which means each parameter a route receives is defined in terms of the type. The route tree looks like what you might expect: a list of paths with HTTP verbs that map to RESTful methods. Routes can also be dynamic so you can include parameters.

Because the error handling is all in one place it's a lot easier to manage than a basic Express application. You can easily define error handlers for 404, 500, and any other error codes, and the framework will send the right thing back to the client.

The validation performed by Express Happiness is done through validator, which is a popular and well-maintained validation module.

Featured

frameworks node ES6 iojs

Nodal: An ES6 API Server

Posted on .

Sometimes I feel like client-side developers are adopting ES6 faster than server-side developers. I certainly have projects where the client uses ES6 and the Node server code is more ES5, mainly because I don't really want to use a transpiler on the server, although I sometimes do like to use Harmony flags.

Alternatively, I could use io.js. Keith Horwood recently sent in a new module that aims to provide an API server and web framework that takes advantage of ES6 features. It's called Nodal (GitHub: keithwhor/nodal, License: MIT, npm: nodal) and currently runs on io.js.

Nodal includes support for models, controllers, templates, migrations, routing, and query composition. It has a command-line tool for creating RESTful resources, and it's designed to work with PostgreSQL.

The example code makes heavy use of new language features like const and classes. The result is very Rails/Django-like. Here's a snippet of a model class:

module.exports = (function() {  
  'use strict';

  const Nodal = require('nodal');

  class Person extends Nodal.Model {
    __preInitialize__() {}
    __postInitialize__() {}
  }

  Person.prototype.schema = Nodal.my.Schema.models.Person;

  Person.prototype.externalInterface = [
    'id',
    'name',
    'age',
    'created_at'
  ];

  return Person;
})();

It doesn't have the same kind of auto-loading magic that you see in Rails -- notice the Nodal module is loaded explicitly. It still feels like idiomatic JavaScript rather than using ES6 to pretend to be something else.

Nodal doesn't use an external ORM, it actually has its own models backed by any-db-postgres. That means Keith is developing features like model relationships. I've tried to develop my own ORM before, and the ORMs I've used before have been very mixed in terms of quality and consistency between releases, so I don't envy the work he has ahead. However, the idea of a RESTful web framework that takes advantage of ES6 for code organisation and clarity is interesting, so let's see what he does with it!

Featured

games education ES6

WarriorJS

Posted on .

WarriorJS (GitHub: olistic/warriorjs, License: MIT, npm: warriorjs) by Matías Olivera is a game that you play by writing ES6 code. Each level is solved by moving the player and interacting with units which include archers and wizards. The simplest level is best by moving the player left, so you just edit Player.js to include the line warrior.walk() in the right place.

WarriorJS

The warrior actually has hit points, and there are two difficulty levels: beginner and intermediate. The levels are JSON files, so you could make your own fairly easily.

Matías will be adding new levels over time, so to check if there are new ones run npm outdated -g warriorjs.