Object JavaScript – ECMAScript 6 Code Preview

imageECMAScript 6 specification and implementation is underway and promises to bring many of the features that you’ve learned about in the posts on Object JavaScript.

This post gives you an idea of what the code looks like in ECMAScript 6. This post doesn’t cover ever feature. But you will learn about how ECMAScript 6 relates to:

  • Scope
  • Arrow Functions and Lexical this
  • Default Function Parameters
  • Classes
  • Inheritance
  • Modules
  • for-of
  • Arrow functions
  • Promises

I won’t come close to covering all the features. But you can get an idea of how ECMAScript 6 works to support the idea of Object JavaScript. Look to the references and to the specification for information about: Parameter handling, multiple return values, collections, destructuring, rest parameters & spread operator, iterators, array comprehension, and more.

Special thanks to Axel Rauschmayer for many of the snippets.

I found two great articles that I am pulling information from:

Scope

JavaScript variables are function-scoped (Object-JavaScript series reference: Scope, Namespaces, “use strict”). This means that, even if there are variables declared in a nested block, they are available throughout the function.

Today: function scope


function orger (x,y) {
if (x > y) {
var tmp = x;
x = y;
y = tmp;
}
console.log(temp === x);
// true
return [x, y];
}

In the code, you see line 3 , var tmp = x; where tmp is available outside its block.

EC6: block scope using let, const


function order(x, y) {
if (x > y)
{
let tmp = x;
x = y;
y = tmp;
}
console.log (tmp === x)
// reference error: tmp not defined
return [ x, y];
}

let, which is like var, except for the fact that it is block scoped instead of function scoped.

let and const behave similarly in the sense that both are block scoped, but with const, the values are read-only and cannot be re-declared later on.

Arrow Functions and Lexical this

Linq uses the arrow (=>) operator uses and expression called a lambda expression. In ECMAScript 6, there is the idea of arrow functions, which seems to me to be similar. It looks like this:


//today
let squares = [1, 2 , 3].map(function (x) {
return x * x
));
// is simplified to
let squares = [1, 2, 3].mpa (x => x * x);

In the post on Using the ‘this’ Keyword I described some of the issues around using this in JavaScript. In ECMAScript 6, you can use the arrow function to peform a lexical this. You can use the arrow function so do something similar to var that = this;


function UiComponent {
let button = document.getElementById('#myButton');
button.addEventListener('click', () => {
console.log('click');
this.handleClick();
});
}

Default Function Parameters

For those of you familiar with C# or TypeScript, you will instantly recognize the ide oa default parameters.

In ECMAScript 6 the default parameters are defined when the functions are defined.


function history(lang = "C", year = 1972) {
return lang + " was created around the year " + year;
}

Classes

In object-oriented programming languages, a class is a representation of an object. It forms the blueprint, while an object is an instance of a class. With regard to JavaScript, it is a class-less programming language and everything is an object. Traditionally, we’ve used functions and prototypes to implement classes.

ECMAScript 6 implements classes with minimal class declaration syntax that can be extremely important to distinguish classes and functions.


class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ',' + this.y + ')';
}
}

view raw

ojs-classes.js

hosted with ❤ by GitHub

Inheritance

In the post on Understanding Prototypes, Inheritance you learned about the messy job of inheritance in Object JavaScript. And it got a little cleaner in Inheritance Using Revealing Module Pattern. In ECMAScript 6, you can use the extends keyword to derive from a parent class, then use the super keyword to call the parent class.


class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color;
}
toString() {
return this.color + ' ' + super();
}
}

view raw

ojs-subclass.js

hosted with ❤ by GitHub

Modules

In programming languages, modules perform isolated discrete functions and are independent of one another. This helps to not only build reusable components across projects, but also keeps errors isolated to the parts related to the current project.

Lots of discussions in my blog about modules, such as Asynchronous Module Definition (AMD) I am a big fan.

You can name exports to be used by other modules. For example:


// in lib/math.js
let notExported = 'abc';
export function square(x) {
return x * x;
}
export const ONE_TWO_THREE = 123;
// in main1.js
import {square} from 'lib/math';
console.log(square(3));
// in main2.js
import as match from 'lib/math';
console.log(math.square(3));

A default provides a way to export a function. For example:


// in myFunc.js
export default function( /* … */) {
// …
}
// in main2.js
import myFunc from 'myFunc';

Or export default a class.


// in MyClass.js
export default class {
// …
}
// in main2.js
import MyClass from 'MyClass'

And there are more features on the way, such as:

  • Rename imports.
  • Module IDs are configurable (default: paths are relative to importing file.
  • Programmatic (conditional) loading of modules.
  • Module loading is configurable.

Object.assign

The Object.assign works in a way similar to _.extend() from Underscore.js, which copies all of the properties in the source objects over to the destination object, and return the destination object.


// Mreges one object into another
class Point {
constructor(x, y) {
Object.assign(this, { x, y });
}
}

for-of

for-of replaces for-in and Array.prototype.forEach(). It works for iterables. For example:


// outputs elements not indices
let myArray = ['hello', 'world'];
for (let elem of myArray) {
console.log(elem);
}
/* output is
hello
world
*/
// in ECMAScript 6
// using the same array
for( let [index, elem] of myArray.entities()) {
console.log(index, elem);
}
/* output is
0 hello
1 world
*/

view raw

ojs-for-of.js

hosted with ❤ by GitHub

Promises

You learned about Promises in several posts:

The ECMAScript 6 implementation will look familiar for the user of Q. If you are using jQuery, it will look a bit different. As a producer, you create a promise and send a result


var promise = new Promise(
function (resolve, reject) { // (A)
// …
if ( /*…*/ ) {
resolve(value); // success
} else {
reject(reason); // failure
}
});

A promise is always in either one of three (mutually exclusive) states:

  • Pending: the result hasn’t been computed, yet
  • Fulfilled: the result was computed successfully
  • Rejected: a failure occurred during computation

A promise is settled (the computation it represents has finished) if it is either fulfilled or rejected. A promise can only be settled once and then stays settled. Subsequent attempts to settle it have no effect.

As a consumer of promise, you are notified of a fulfillment or a rejection via reactions – callbacks that you register with the method then():


promise.then(
function (value) { /* fulfillment */ },
function (reason) { /* rejection */ }
);

References