Carlos Blé
@carlosble
Thanks to the help provided by my colleague…
Alfredo Casado!
ES6 Simplified
Why ES6? (Also known as ES2015)
➔ Is the standard since June 2015!
➔ Gets rid of common and annoying gotchas
➔ Preserves all the good parts
➔ Syntactic sugar improves readability
➔ Powerful tools and libraries
➔ ES5 is still deployed into production
@carlosble
Simplicity
➔ Among all ES6 features we favor those that are
powerful yet simple. We like simple code:
◆ Pass all tests
◆ Clear, expressive & consistent
◆ Duplicates no behavior
◆ Small - Minimal methods & modules
Kent Beck
It’s all about the context!
Developing applications is not like
developing a library or a framework
Cost of understanding/maintaining code
VS
Cost of changing client code
Adapt your practices to the context
@carlosble
Power lies in the functions
@carlosble
1 export default {add, subtract};
2 // export default {add: add,
subtract: subtract};
3
4 function add(a + b){…}
5 function subtract(a + b){…}
Usage:
import calculator from ‘./m.js’;
calculator.add(1,1);
Modules (singletons):
1 export default {calculator};
2 // export default {calculator:
calculator};
3 function calculator(){
4 return {add, subtract};
5 }
6 function add(a + b){…}
7 function subtract(a + b){…}
Usage:
import buildCalculator from ‘./f.js’
let calculator = buildCalculator();
calculator.add(1,1);
Factory functions:
No need for IIFE anymore!
Do you really need to save memory?
Syntactic sugar for prototypes
class Person {
constructor(name) {
this.name = name;
}
hello() {
return `hi ${this.name}`;
}
}
function Person(name) {
this.name = name;
}
Person.prototype.hello = function()
return "hi " + this.name;
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
Warning: We avoid classes as much as we can
@carlosble
Aur revoir var!
@carlosble
1
2
3
4
5
6
7
8
9
10
11
Welcome let & const
function useLetInstead(){
const items = ['cat','dog'];
const len = items.length;
const f = [];
for (let i = 0; i < len-1; i++){
f.push(() => items[i]);
}
console.log(f[0]());
}
useLetInstead();
function doNotUseVar(){
var items = ['cat','dog'];
var len = items.length;
var f = [];
for (var i = 0; i < len-1; i++){
f.push(function(){
return items[i];
});
}
console.log(f[0]());
}
doNotUseVar();
1
2
3
4
5
6
7
8
9
10
11
Destructuring
const book = {
"author": {
"name": "Bob Sponge",
"email": "bob@gmail.com"
},
"title": "Under the sea",
"other": "stuff"
}
let {author: {name,email}, title} = book
console.log(name); // “Bob Sponge”
console.log(email); // “bob@gmail.com”
console.log(title); // “Under the sea”
var name = book.author.name;
var email = book.author.email;
var title = book.title;
console.log(name); // “Bob Sponge”
@carlosble
Simulating named parameters
function errorMessage({
message,
width = 300,
height = 300,
icon = ‘error.png’}){
...
}
function errorMessage(options){
options = options || {};
var width = options.width || 300;
var height = options.end || 300;
var icon = options.icon || ‘error.png’;
...
}
1
2
3
4
5
6
7
1
2
3
4
5
6
7
errorMessage({ message: ‘Ups! sorry’, icon: ‘other-icon.png’});
@carlosble
Destructuring + default values
function sum({x = 0, y = 0} = {}){
return x + y;
}
function destruct({a: {x}, b = 1}){
return x + b;
}
sum({x:5});
sum();
destruct();
destruct({a:{x:1}, b: 5});
destruct({a:{x:1}});
destruct({b:1});
1
2
3
4
5
6
7
8
9
10
11
12
13
@carlosble
Simulating mandatory parameters
function mandatory() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = mandatory()) {
return mustBeProvided;
}
function foo(mustBeProvided) {
if (arguments.length < 1) throw ...
if (mustBeProvided === undefined) ...
}
1
2
3
4
5
6
7
1
2
3
4
@carlosble
Rest operator
function calculate(multiplier, ...numbers) {
let sum = numbers.reduce(
(accumulator, num) => accumulator + num
);
return multiplier * sum;
}
function calculate() {
var numbers = Array.prototype.slice.call(arguments)
var multiplier = numbers.shift()
var sum = numbers.reduce(
function(accumulator, num){ return accumulator + num;}
)
return multiplier * sum;
}
1
2
3
4
5
6
1
2
3
4
5
6
7
8
@carlosble
Promises
function sendFeedback(customer, phone, answers) {
const promises = [];
for (let answer of answers) {
promises.push(new Promise((resolve) => {
answer.send(customer, phone, resolve);
}));
}
return promises;
}
const promises = sendFeedback(customer, phone, answers);
Promise.all(promises).then(() => showSuccessMessage());
1
2
3
4
5
6
7
8
9
10
11
12
@carlosble
Babel
@carlosble
Tools
➔ Gulp (workflow automation)
➔ Babel (compile to ES5)
➔ Browserify (require in the browser)
➔ ESLint (linter)
➔ Karma (test runner)
➔ Nodemon (manage node servers)
➔ Jasmine (unit tests)
➔ PhantomJs (unit & integration tests)
➔ Nightwatch (end2end tests)
@carlosble
Good stuff & References
@carlosble
★ ES6 Katas
http://es6katas.org/
★ Tests end2end con Nightwatch [es] http://miguelviera.com/blog/testing-e2e-con-
nightwatch-js-y-browserstack/
★ Tests de integracion: Gulp+Karma+Jasmine+Nodemon [es]
http://miguelviera.com/blog/integration-tests-con-gulp-karma-jasmine-phantomjs-y-nodemon/
★ Writing a Gulpfile [en]
http://www.carlosble.com/2015/09/es6-browserify-babel-gulp-jasmine/
★ How to fix de ES6 class keyword [en] https://medium.com/javascript-scene/how-to-fix-the-
es6-class-keyword-2d42bb3f4caf#.x4qojp84n
★ Let and Const [en]
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.pliox5rso
★ Let and Const in Depth [en]
https://hacks.mozilla.org/2015/07/es6-in-depth-let-and-const/
Books! read books!
@carlosble
● Implementation Patterns - Kent Beck
● JavaScript Allongé - Reginald Braithwaite
● JavaScript The Good Parts - Douglas Crockford
● 4 Rules of Simple Design - Corey Haines
More books: http://www.carlosble.
com/2011/02/books-you-should-read/
Bonus Track
Do you really need inheritance?
@carlosble
1
2
3
4
5
6
7
8
9
10
Template method implemented with functional inheritance:
function childClazz(){
const self = baseClazz({
compute: () => 3
});
return self;
}
console.log(
childClazz().template());
function baseClazz(methods = {}){
let compute = () => 2;
compute = methods.compute ||
compute;
return {
template : () => compute() + 1
};
}
console.log(
baseClazz().template());
1
2
3
4
5
6
7
8
9

ES6 Simplified

  • 1.
    Carlos Blé @carlosble Thanks tothe help provided by my colleague… Alfredo Casado! ES6 Simplified
  • 2.
    Why ES6? (Alsoknown as ES2015) ➔ Is the standard since June 2015! ➔ Gets rid of common and annoying gotchas ➔ Preserves all the good parts ➔ Syntactic sugar improves readability ➔ Powerful tools and libraries ➔ ES5 is still deployed into production @carlosble
  • 3.
    Simplicity ➔ Among allES6 features we favor those that are powerful yet simple. We like simple code: ◆ Pass all tests ◆ Clear, expressive & consistent ◆ Duplicates no behavior ◆ Small - Minimal methods & modules Kent Beck
  • 4.
    It’s all aboutthe context! Developing applications is not like developing a library or a framework Cost of understanding/maintaining code VS Cost of changing client code Adapt your practices to the context @carlosble
  • 5.
    Power lies inthe functions @carlosble 1 export default {add, subtract}; 2 // export default {add: add, subtract: subtract}; 3 4 function add(a + b){…} 5 function subtract(a + b){…} Usage: import calculator from ‘./m.js’; calculator.add(1,1); Modules (singletons): 1 export default {calculator}; 2 // export default {calculator: calculator}; 3 function calculator(){ 4 return {add, subtract}; 5 } 6 function add(a + b){…} 7 function subtract(a + b){…} Usage: import buildCalculator from ‘./f.js’ let calculator = buildCalculator(); calculator.add(1,1); Factory functions: No need for IIFE anymore!
  • 6.
    Do you reallyneed to save memory? Syntactic sugar for prototypes class Person { constructor(name) { this.name = name; } hello() { return `hi ${this.name}`; } } function Person(name) { this.name = name; } Person.prototype.hello = function() return "hi " + this.name; } 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 Warning: We avoid classes as much as we can @carlosble
  • 7.
    Aur revoir var! @carlosble 1 2 3 4 5 6 7 8 9 10 11 Welcomelet & const function useLetInstead(){ const items = ['cat','dog']; const len = items.length; const f = []; for (let i = 0; i < len-1; i++){ f.push(() => items[i]); } console.log(f[0]()); } useLetInstead(); function doNotUseVar(){ var items = ['cat','dog']; var len = items.length; var f = []; for (var i = 0; i < len-1; i++){ f.push(function(){ return items[i]; }); } console.log(f[0]()); } doNotUseVar(); 1 2 3 4 5 6 7 8 9 10 11
  • 8.
    Destructuring const book ={ "author": { "name": "Bob Sponge", "email": "bob@gmail.com" }, "title": "Under the sea", "other": "stuff" } let {author: {name,email}, title} = book console.log(name); // “Bob Sponge” console.log(email); // “bob@gmail.com” console.log(title); // “Under the sea” var name = book.author.name; var email = book.author.email; var title = book.title; console.log(name); // “Bob Sponge” @carlosble
  • 9.
    Simulating named parameters functionerrorMessage({ message, width = 300, height = 300, icon = ‘error.png’}){ ... } function errorMessage(options){ options = options || {}; var width = options.width || 300; var height = options.end || 300; var icon = options.icon || ‘error.png’; ... } 1 2 3 4 5 6 7 1 2 3 4 5 6 7 errorMessage({ message: ‘Ups! sorry’, icon: ‘other-icon.png’}); @carlosble
  • 10.
    Destructuring + defaultvalues function sum({x = 0, y = 0} = {}){ return x + y; } function destruct({a: {x}, b = 1}){ return x + b; } sum({x:5}); sum(); destruct(); destruct({a:{x:1}, b: 5}); destruct({a:{x:1}}); destruct({b:1}); 1 2 3 4 5 6 7 8 9 10 11 12 13 @carlosble
  • 11.
    Simulating mandatory parameters functionmandatory() { throw new Error('Missing parameter'); } function foo(mustBeProvided = mandatory()) { return mustBeProvided; } function foo(mustBeProvided) { if (arguments.length < 1) throw ... if (mustBeProvided === undefined) ... } 1 2 3 4 5 6 7 1 2 3 4 @carlosble
  • 12.
    Rest operator function calculate(multiplier,...numbers) { let sum = numbers.reduce( (accumulator, num) => accumulator + num ); return multiplier * sum; } function calculate() { var numbers = Array.prototype.slice.call(arguments) var multiplier = numbers.shift() var sum = numbers.reduce( function(accumulator, num){ return accumulator + num;} ) return multiplier * sum; } 1 2 3 4 5 6 1 2 3 4 5 6 7 8 @carlosble
  • 13.
    Promises function sendFeedback(customer, phone,answers) { const promises = []; for (let answer of answers) { promises.push(new Promise((resolve) => { answer.send(customer, phone, resolve); })); } return promises; } const promises = sendFeedback(customer, phone, answers); Promise.all(promises).then(() => showSuccessMessage()); 1 2 3 4 5 6 7 8 9 10 11 12 @carlosble
  • 14.
  • 15.
    Tools ➔ Gulp (workflowautomation) ➔ Babel (compile to ES5) ➔ Browserify (require in the browser) ➔ ESLint (linter) ➔ Karma (test runner) ➔ Nodemon (manage node servers) ➔ Jasmine (unit tests) ➔ PhantomJs (unit & integration tests) ➔ Nightwatch (end2end tests) @carlosble
  • 16.
    Good stuff &References @carlosble ★ ES6 Katas http://es6katas.org/ ★ Tests end2end con Nightwatch [es] http://miguelviera.com/blog/testing-e2e-con- nightwatch-js-y-browserstack/ ★ Tests de integracion: Gulp+Karma+Jasmine+Nodemon [es] http://miguelviera.com/blog/integration-tests-con-gulp-karma-jasmine-phantomjs-y-nodemon/ ★ Writing a Gulpfile [en] http://www.carlosble.com/2015/09/es6-browserify-babel-gulp-jasmine/ ★ How to fix de ES6 class keyword [en] https://medium.com/javascript-scene/how-to-fix-the- es6-class-keyword-2d42bb3f4caf#.x4qojp84n ★ Let and Const [en] https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.pliox5rso ★ Let and Const in Depth [en] https://hacks.mozilla.org/2015/07/es6-in-depth-let-and-const/
  • 17.
    Books! read books! @carlosble ●Implementation Patterns - Kent Beck ● JavaScript Allongé - Reginald Braithwaite ● JavaScript The Good Parts - Douglas Crockford ● 4 Rules of Simple Design - Corey Haines More books: http://www.carlosble. com/2011/02/books-you-should-read/
  • 18.
  • 19.
    Do you reallyneed inheritance? @carlosble 1 2 3 4 5 6 7 8 9 10 Template method implemented with functional inheritance: function childClazz(){ const self = baseClazz({ compute: () => 3 }); return self; } console.log( childClazz().template()); function baseClazz(methods = {}){ let compute = () => 2; compute = methods.compute || compute; return { template : () => compute() + 1 }; } console.log( baseClazz().template()); 1 2 3 4 5 6 7 8 9