es6: features + rails
TRANSCRIPT
ES6• ES6 is short name of “ECMAScript Language
Specification, Edition 6”
• It’s a new version of ECMAScript
• ECMAScript is the official name of JavaScript
• ES6 provides very nice powerful features
• ES6 helps writing more modular and less quirky code in JavaScript.
ES6 Features• Let + Const
• Template string
• Destructuring Assignment
• Default + Rest + Spread
• Loops, Generators
• Enhanced object literals
• Map + Set
• Arrows
• Modules
• Classes
Let + Const
• Variables before ES6 are function scoped
• ‘let’ & ‘const’ are block-scoped binding constructs
• ‘let’ is the new variable
• ‘const’ is single-assignment.
// ES5
"use strict";
function superHeroes() { var superHero1;
{ superHero1 = "Spider-Man";
var superHero2 = "Batman";
console.log(superHero1); // => "Spider-Man" console.log(superHero2); // => "Batman" }
console.log(superHero1); // => "Spider-Man" console.log(superHero2); // => "Batman"}
superHeroes();
function superHeroes() { let superHero1;
{ superHero1 = "Spider-Man";
let superHero2 = "Batman";
console.log(superHero1); // => "Spider-Man" console.log(superHero2); // => "Batman" }
console.log(superHero1); // => "Spider-Man" console.log(superHero2); // => "superHero2 is not defined"}
superHeroes();
// ES6
function superHeroes(){ const NAME = 'HULK'
{ const COLOUR = 'green'
console.log(NAME); // => 'HULK' console.log(COLOUR); // => 'green'
}
console.log(NAME); // => 'HULK' console.log(COLOUR); // => COLOUR is not defined
}
superHeroes();
// ES6
function superHeroes(){ const NAME = 'HULK'
{ const COLOUR = 'green'
console.log(NAME); console.log(COLOUR);
NAME = 'other_name'; }
console.log(NAME); console.log(COLOUR);
}
superHeroes();
// Error: ”NAME" is read-only
Template Strings
• A new way of string interpolation
• It adds syntactic sugar for constructing strings
• Easy to handle multiline strings
// ES6
// basic template string creation.var str = `How you doing?`;var name = 'Joey';
var output = `${name}: ${str}`;
console.log(output) // => Joey: How you doing?
var first_name = 'john';var last_name = 'smith';
// Instead of handlling this stuff'HTTP://example.com/first_name=' + first_name + '&last_name=' + last_name
// we can do this very easily.
`HTTP://example.com/first_name=${first_name}&last_name=${last_name}`
// Multiple Strings.
`Oh, I'm sory, Did I break your concentration?`
// => Oh, I'm sory,// => Did I break your concentration?
Enhanced Object Literals
• Object literal is the most popular pattern in JavaScript
• Based on its syntax, JSON was built
• ES6 recognised the popularity of the object literal and extended it in several ways to make it more powerful and even more succinct
Property Initializer Shorthand
// ES5function createPost(title, content) { return { title: title, content: content };}
//ES6function createPost(title, content) { return { title, content };}
Method Initializer Shorthand
// ES5var car = { name: "Mustang GT500", startEngine: function() { console.log('starting...'); }};
//ES6var car = { name: "Mustang GT500", startEngine(){ console.log('starting...'); }};
Computed Property Names
// ES5var car = { "name": "Mustang GT500"};
console.log(car["name"]); // "Mustang GT500"
// ES6var maxSpeed = "max speed";var prefix = "min ";
var car = { "name": "Mustang GT500", [maxSpeed]: "160", [prefix + "speed"]: "0"};
console.log(car["name"]); // "Mustang GT500"console.log(car["max speed"]); // "160"console.log(car["min speed"]); // "0"
Destructuring Assignment
• Destructuring allows you to pattern match against array and objects
• It extracts specific values to the individual local variables
// ES6
// Array matchingvar [a, , b] = [1,2,3];
console.log(a, b); // => 1 3
// Swapping using array[b, a] = [b, a];console.log(b, a); // => 3 1
// Object Matchingvar {emacsUser, atomUser, vimUser } = getEditorUserInfo();
function getEditorUserInfo(){ return { vimUser: 'Tim', emacsUser: 'Sam', atomUser: 'Chris' };}
console.log(emacsUser); // => 'Sam'console.log(vimUser); // => 'Tim'console.log(atomUser); // => 'Chris'
// ES6
// Object Deep Matchingvar { user: { fN: firstName, lN: lastName } } = getUserInfo();
function getUserInfo(){ var user = { user: { fN: 'Adam', lN: 'Collins'} } return user;}
console.log(firstName); // 'Adam'console.log(lastName); // 'Collins'
// ES5function dailyWorkIncome(workHours, hourlyRate, bonus) { hourlyRate = hourlyRate || 25; bonus = bonus || 0
return (workHours * hourlyRate) + bonus;}
dailyWorkIncome(7, 30); // 175
// ES6function dailyWorkIncome(workHours, hourlyRate = 25, bonus = 0) { return (workHours * hourlyRate) + bonus;}
dailyWorkIncome(7); // 175dailyWorkIncome(7, 30); // 210dailyWorkIncome(7, 30, 15); // 225
//ES6
function userNames(mainName, ...socialNames) { var allNames = []; allNames.push(mainName);
for (let i of socialNames) { allNames.push(i); }
return allNames;}
userNames('MyName', 'TwitterName', 'GithubName');
// ["MyName","TwitterName","GithubName"]
Loops//ES5
// Using forEeach on an array.['John', 'Smith'].forEach(function(item){ console.log(item);});
// Using for-in for objectvar obj = { name: 'Hulk', color: 'green'}
for(var k in obj) { console.log(obj[k]);}
Loops//ES6
// Using for-of for an arrayfor(let item of ['John', 'Smith']){ console.log(item);}
// Using for-of for an objectvar obj = { name: 'Hulk', color: 'green'}
for(let k of Object.keys(obj)) { console.log(obj[k]);}
Generators• Generator is function which has multiple
return points
• Allows you to “pause & resume” a function
• Interruptible Computations
• Shallow Coroutines
• Great for simplifying asynchronous code
function* numbers(){ var n = 1; var a; while(n < 3) { a = yield n++; console.log('a:', a); }};
var gen = numbers();console.log(gen.next());console.log(gen.next(2));console.log(gen.next("three"));
// {"value":1,"done":false}// a: 2// {"value":2,"done":false}// a: three// {"done":true}
function* numbers(){ var n = 1; var a; while(true) { yield n++; }};
for (var n of numbers()) { if (n > 50) break; console.log(n);}
// output:// 1// 2// 3// .// .// .// 50
Map + Set
• Efficient data structure for common algorithms
• These provide methods likes ‘entries()’, ‘values()’ & ‘keys()’
// Map
var m = new Map();m.set("name", 'John');
var s = new Set();s.add('Apple').add('Banana');
m.set('fruits', s);
for(let entry of m.entries()){ console.log(entry);};// ["name","John"]// ["fruits",["Apple","Banana"]]
for(let entry of m.keys()){ console.log(entry);};// name// fruits
for(let entry of m.values()){ console.log(entry);};// John// ["Apple","Banana"]
// Set
var s = new Set();s.add('Apple').add('Banana').add('Apple');console.log(s.size === 2); // trueconsole.log(s.has('Apple') === true); // true
for(let entry of s.entries()){ console.log(entry);};
// ["Apple","Apple"]// ["Banana","Banana"]
for(let entry of s.keys()){ console.log(entry);};
// Apple// Banana
for(let entry of s.values()){ console.log(entry);};
// Apple// Banana
Arrows• One of the cool features of ES6
• Arrow function has shorter syntax “=>” syntax compared to regular function
• Unlike functions, arrows bind the “this” value as their surrounding code
• Arrow functions are always anonymous functions
• It throws the error when we use it with “new”
// ES5
var sum = function(num1, num2) { return num1 + num2;};
var evens = [2,4,6,8];
var odds = evens.map(function(v){ return v + 1;});
// ES6var sum = (num1, num2) => num1 + num2;
var evens = [2,4,6,8];
var odds = evens.map(v => v + 1);
//ES5
var name = 'Tom';var obj = { name: 'Jerry', sayName: function(){ console.log(this.name); }, greet: function(){ setTimeout(function(){ console.log('Hi,' + this.name ); },100); }};obj.sayName(); // logs Jerryobj.greet(); // logs Hi, Tom
//ES6
var name = 'Tom';var obj = { name: 'Jerry', sayName: function(){ console.log(this.name); }, greet: function(){ setTimeout( ()=> { console.log('Hi,' + this.name ); },100); }};obj.sayName(); // logs Jerryobj.greet(); // logs Hi, Jerry
Modules// lib/math.js
export const pi = 3.141593;
export function double(x){ return x + x;}
// app.jsimport * at math from "lib/math";console.log(math.pi); // 3.141593console.log(math.double(10)); // 20
// other_app.jsimport {pi, double} from "lib/math";console.log(pi); // 3.141593console.log(double(10)); // 20
// ES5
function Car(name) { this.name = name;}
Car.prototype.getName = function() { console.log(this.name);};
let car = new Car("Mustang GT500");car.getName(); // "Mustang GT500"
console.log(car instanceof Car); // trueconsole.log(car instanceof Object); // true
// ES6class Car {
// equivalent of the PersonType constructor constructor(name) { this.name = name; }
// equivalent of PersonType.prototype.sayName sayName() { console.log(this.name); }}
let car = new Car("Mustang GT500");car.sayName(); // outputs "Mustang GT500"
console.log(car instanceof Car); // trueconsole.log(car instanceof Object); // true
ES6 setup on Rails
• Work in progress in Sprockets 4.x
• Still, we can use sprockets-es6 gem
• sprockets-es6 gem uses babel gem internally to transpile your ES6 file to ES5
• Another way using Node.js and Gulp
ES6 setup on Rails
In your Gemfile, add these gems,
• gem 'sprockets', ‘>=3.0.0.beta'
• gem ‘sprockets-es6’
Run bundle install.
Write down your ES6 code in files using .es extension and thats it :)