ES6 + ES7 = Awesomeness
Before we start...
Did you know:
- ECMAScript != Javascript?
- Harmony = ES6 = ES2015?
- ES7 = ES.Next = ES2016?
- Polyfills provide support to features not yet available in browsers?
- Transpilers are compilers with a fancy name?
Babel Transpiler
babel.transform(ES6 / ES7) => ES5
let hello = (name) => `Hello ${name}`
hello('World')
Warm up
Probably stuff you already know...
- Improved String API
- Object literal initialization
- Class and Class Expressions
- var vs let vs const
- Arrow functions
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
- Spread Operator
- Rest Operator
- Simulating Named Parameters
- Generators
- Async functions
- Decorators
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