0Users

ES6 + ES7 = Awesomeness

Before we start...

Did you know:

Babel Transpiler

babel.transform(ES6 / ES7) => ES5

let hello = (name) => `Hello ${name}`
hello('World')

Warm up

Probably stuff you already know...

Improved String API

startsWith, endsWith, repeat, string templates...

const message = "Well, hello!";
message.startsWith('Well, ');

Object literal initialization

Shorthands that save you some typing...

let name = 'Borges'
let age = 30
let person = { name: name, age: age }
person

Class and Class Expressions

Because every other language has it?

class User {
  constructor(name='guest') {
    this.name = name
  }
  
  greet(someone, message='Hi') {
    return `${this.name}: ${message} ${someone}!`
  }
}
new User('Diego').greet('Ben')

var vs let vs const

stating the obvious

const age = 30
// age += 1

var vs let

It's all about scopes

var birthday = true
if (birthday) {
  var age = 30
}
age

var vs let

Hoisting

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

developer.mozilla.org

Hoisting

The Problem

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log('item:', i);
  }, 1000);
}
i

Hoisting

Workaround: IIFE

for (var i = 0; i < 3; i++) {
  (function() {
    var index = i
    setTimeout(function() {
      console.log('item', index);
    }, 1000);
  })()
}
i

Hoisting

The solution

for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log('item:', i);
  }, 1000);
}
// i

Arrow Function

(a, b) => a + b

[1, 2, 3].map(function(n) { return n ** 3 })

Arrow Function

Lexical "this": self is no more...

var project = {
  taxRate: 1.2,
  items: [10, 20, 3.5],
  cost() {
    return this.items.reduce(function(sum, item) {
      return sum + (item * this.taxRate)
    })
  }
}
project.cost()

Arrow Function

Lexical "this": self is no more...

var project = {
  taxRate: 1.2,
  items: [10, 20, 3.5],
  cost() {
    return this.items.reduce((sum, item) => sum + (item * this.taxRate))
  }
}
project.cost()

Lets get serious, now...

For .. of

a proper for .. in loop

let items = [1, 2, 3]
for (let item of items) {
  console.log(item)
}

Spread Operator

varargs with lasers <3

let a = [1, 2, 3]
let b = [...a, 4]
b

Spread Operator

Works on objects too!

let person = { name: 'Borges', email: 'drborges.cic@gmail.com' }
let user = { ...person, name: 'diego', login: 'diego.borges' }
user

Rest Operator

Destructuring to construct

let [ head, ...tail ] = [1, 2, 3, 4];
tail
// let { name } = { name: 'Borges', age: 30 }
// new Date(...[2015, 1, 1]);

Rest Operator

Simulating ruby named parameters

function greet({ person, message } = { person: 'Guest', message: 'Hello' }) {
  return `${message}, ${person}!`
}
greet({ person: 'Bruno', message: 'Hi' })

Generators

The foundation for iterators

function *integers() {
  let i = 0
  while (true) {
    yield i++
  }
}
let iterator = integers()
iterator.next().value

Async functions

I Promise, it feels like imperative programming

async function fetchGithubOrgs() {
  let resp = await fetch('https://api.github.com/users/drborges/repos')
  let repos = await resp.json()
  return repos.map(r => r.name)
}
fetchGithubOrgs().then((reposNames) => console.log(reposNames.join("\n")))

Decorators

Currently disabled on Babel 6

function Testable (target) { target.isTestable = true }
@Testable
class Authenticator {}
Authenticator.isTestable

Questions?

Source code at github.com/drborges