My Excellent Presentation

ES6: The Good Parts

josh@josh.earth

Mozilla Dev Rel

What is ES6?

Why ES6 matters

Too much new

Let's be useful instead

Four good parts

The Problems with Variables

Variables always vary

var VARS = {
    foo
        set = function() { }
        get = function() { return 42 }
}
VARS.foo = 42; // now I have a constant
        

Function Scoping

function badCode() {
    if(foo) {
        var x = 5;
    }
    if(bar) {
        console.log(x);
    }
}
        

Hoisting

function badCode() {
    console.log("foo is",foo);
    var foo = 'bar';
}
        

Hoisting

for(var i=0; i<5; i++) {
    console.log(i);
}
console.log(i);
        

A better way

const and let

const

function test() {
    const foo = 'bar';
    foo = 'baz'; //error
}

let

function goodCode() {
    if(foo) {
        let x = 5;
    }
    if(bar) {
        console.log(x); //error
    }
}        

let

function goodCode() {
    for(let i=0; i<5; i++) {
        console.log(i);
    }
    console.log(i); //error
}

Template Literals: Super Strings

var q  = 'foo';
var qq = "foo";

var bq = `foo`;

var qq = "Sally sells \"sea shells\"";
var bq = `Sally sells "sea shells"`;

Multi-line Strings

var qq = "this is a very long"
    + " piece of text that goes over several lines"
    + " and would require silly hacks";

var bq = `this is a very long
    piece of text that goes over several lines
    and would require silly hacks`;

Template Strings

var name = "Alice";
var greeting = `Good morning ${name}`;
var amount = 5;
var price = 3;
var sales = `That costs ${amount*price} dollars`;

HTML Templates

var template = `
  <div>
      <h3>Good morning ${name}</h3>
      <p>
          That item will cost you
          <b>${amount*price}</b>
          dollars.
      </p>
  </div>
`

Arrow Functions

Good

var output = [];
for(var i=0; i<input.length; i++) {
    output[i] = input[i] * 2;
}

Better

var output = input.map(function(x) {
    return x * 2;
});

Best

var output = input.map((x)=>x*2);

Arrow Functions

function (x) {
    return x * 2;
}
(x) => {
    return x * 2;
}

Arrow Functions

(x) => { return x * 2; }

Arrow Functions

(x) => x * 2
var output = input.map((x)=>x*2);

The curse of this

function App() {
    this.clicked = false;

    var button = document.getElementById('button');
    button.addEventListener('click', function(evt) {
        this.clicked = true; //won't do what you think
    });
}

The self pattern

function App() {
    this.clicked = false;

    var button = document.getElementById('button');

    var self = this;
    button.addEventListener('click', function(evt) {
        self.clicked = true;
    });
}

Function binding

function App() {
    this.clicked = false;

    var button = document.getElementById('button');

    var callback = (function(evt) {
        this.clicked = true
    }).bind(this);

    button.addEventListener('click',callback);
}
function App() {
    this.clicked = false;

    var button = document.getElementById('button');
    button.addEventListener('click',()=>{
        this.clicked = true;
    });
}

Arrow Functions are Awesome

Promises for Long Running Work

Pyramid of Doom

fs.readFile("file.txt", function(err, file) {
    db.fetchNames(function(err, names) {
        processFile(file, names, function(err, outfile) {
            fs.writeFile('file.txt',outfile, function(err, status) {
                console.log("we are done writing the file");
            })
        });
    })
});

What is a promise

var prom = makeSomePromise();
//value isn't ready yet
prom.then((value)=>{
    //do something with the value
})
fs.readFile("file.txt")
    .then((file) => {
        return db.fetchNames().then((names)=>{
            return processFile(file,names)
        })
    })
    .then((outfile)=>{
        return fs.writeFile('file.txt',outfile);
    })
    .then(()=>{
        console.log("we are done writing the file");
    });
var proms = filenames.map((name)=> readFile(name));
Promise.all(proms).then((files)=>{
    console.log(`we have ${files.length} files`);
});
        
Promise.all([
    fs.readFile("file.txt"),
    db.fetchNames()
])
.then((vals) => processFile(vals[0],vals[1]))
.then((outfile)=> fs.writeFile('file.txt',outfile))
.then(()=> console.log("we are done writing the file"));
        
Promise.all([
    fs.readFile("file.txt"),
    db.fetchNames()
])
.then((vals) => processFile(vals[0],vals[1]))
.then((outfile)=> fs.writeFile('file.txt',outfile))
.then(()=> console.log("we are done writing the file"))
.catch((e) => {
    console.log("some error happened");
})
.then(()=> console.log("we are done either way"));
        
function makePromise(foo,bar) {
    return new Promise((resolve, reject) => {
        try {
            //do long stuff
            resolve(value);
        } catch {
            reject(error);
        }
    });
}
        
var url = "http://api.silly.io/api/list/"
              +"e3da7b3b-976d-4de1-a743-e0124ce973b8?format=json";

var xml = new XMLHttpRequest();
xml.addEventListener('load', function() {
    var result = JSON.parse(this.responseText);
    console.log(result);
});
xml.open("GET",url);
xml.send();
function doGet(url) {
    return new Promise((resolve,rej)=>{
        var xml = new XMLHttpRequest();
        xml.addEventListener('load', function() {
            var result = JSON.parse(this.responseText);
            resolve(result);
        });
        xml.addEventListener('error',function(error) {
            reject(error);
        });
        xml.open("GET",url);
        xml.send();
    });
}
var url = "http://api.silly.io/api/list/"
    +"e3da7b3b-976d-4de1-a743-e0124ce973b8?format=json";
doGet(url).then((obj)=>{
    console.log(obj);
});
var url = "http://api.silly.io/api/list/"
            +"e3da7b3b-976d-4de1-a743-e0124ce973b8?format=json";
fetch(url).then((obj) => {
    console.log(obj);
});

Promises are awesome

Four good parts

Bonus Features

Array

var values = [1,2,3,4,5,6,7,8,9,10];

values.forEach((x)=>console.log(x));
var doubled = values.map((x) => x*2);

//find all values that match the filter
var evens = values.filter((x)=>x%2==0);

//true if at least one item matches
var any = values.some((x) => x > 10);

//find the first that matches
var six = values.find((x) =>  x >= 6);
//find the index of the first that match
var index = values.findIndex((x) =>  x >= 6);
//reduce the array to a single value
var sum = values.reduce((a,b) => a+b, 0);
        
var obj = {
    first:'Alice',
    middle:'N',
    last:'Wonderland',
    age:8,
    height:45,
}
Object.keys(obj).forEach((key)=>{
    console.log("key = ", key);
    console.log("value = ", obj[key]);
});
        

Things to definitely avoid for now

Things to definitely avoid for now

Class Syntax

class Foo extends Bar {
    constructor(stuff) {
        super(stuff);
        this.first = "first name"
    }
    doStuff() {
    }
    doMoreStuff() {
    }
}

async / await syntax

function getJSON() {
    //return a promise
}
const makeRequest = async () => {
  console.log(await getJSON())
  return "done"
}
makeRequest()

        

Can I Use them now

caniuse.com

Code for the future

Thank you!

currnet slide
next slide
my notes
questions