Moving to ES6

Women Who Code Logo

Welcome!

Welcome!

Some "rules"

  • We are here for you!
  • Every question is important
  • Help each other
  • Have fun

Our Workshop Activity

A 100% JavaScript Shopping Cart (featuring emoji 😉)

See the Pen WWC ES6 Activity - Solution by Liz Shaw (@anythingcodes) on CodePen.

Background

What is ES6?

📄 Standard:

  • ECMAScript, abbreviated ES
  • Describes features, syntax, and behavior of all implementations
  • Think of it as a ruleset or blueprint


✍ Implementation:

  • JavaScript, the implementation of the ECMAScript standard
  • Implementations track standards
ES6's relationship to JavaScript
The standard, ECMAScript, is the ruleset, or blueprint
The implementation, JavaScript, is the language that uses that ruleset's plan, or built house/product

📝 We'll implement the new features from version 6 of ECMAScript using JavaScript

What ES6 can do for you

  1. Fix scoping problems
  2. Write cleaner, easier-to-understand code
  3. New functionality for working with arrays and objects
  4. A built-in helper for making AJAX requests
  5. Encourage the ✨powers✨ of object-oriented programming

( 1 )Fix scoping problems

Scopes 🔬

  1. Function Scopes: YES

    Variables defined inside of a function are not accessible from the outside scope

          function myFunctionScope() {
            var a = 'alpha';
            return a;
          }
          console.log(a); // undefined										
    				
  2. Block Scopes (a.k.a. lexical scopes): NO

    Any variables declared within { } are accessible only within the { }

          var myBlockScope = true;
          if (myBlockScope) {
            var z = 'zeta';
          }
          console.log(z); // 'zeta'										
    					

Wait what?

What is going on here?!

var ignores block scope and only respects function scope

Why is this a problem?

Unpredictable and hard to control

CodePen Example »

How does ES6 fix block scoping?

Use let and const instead of var

  • const is for constants
  • let is for variables whose value will change (Example »)
  • Use const by default, but change to let when you need to change the value

CodePen Example »

Do you still need var?

No 😊

Only one potential case: If you have code that should be available from the global object (window in browsers), e.g. if you need to access code across frames or windows

👆 This is rare and should generally be avoided

How does ES6 help with function scope issues?

  • With arrow functions: =>
  • Usually used to fix issues with the this keyword

ES5

var getMessage = function(name) {
  return 'Hello ' + name;
}

ES6

const getMessage = name => 'Hello ' + name;

Making an arrow function:

  1. Remove the word function
  2. Place a fat arrow (=>) after parameters

Trimming it down:

  • If there's only one parameter, remove the surrounding parentheses ()
  • If there's only one expression in the function body, remove { } and return (implicit return)

The this keyword

The this keyword determines context

const obj = {
  name: 'Zeta',
  getName: function() {
    console.log(this.name);
  }
};
			
obj.getName(); // Zeta

There's this One Problem

Binding and changing this in functions is one of the most common JavaScript errors

Computer frustrationIt's possible to mistakenly affect one object when you meant to affect another

var self = this;
var _this = this;
var that = this;

🤦

What is this problem?

Let's take a look

See the Pen Arrow functions and `this` by Liz Shaw (@anythingcodes) on CodePen.

Can arrow functions help?

  • Arrow functions do not have a this 🌟
  • The value of this is lexically fetched from the scope the arrow function sits inside

See the Pen Arrow functions and `this` by Liz Shaw (@anythingcodes) on CodePen.

( 2 )Write cleaner, easier-to-understand code

Template Strings

Allow multi-line strings

Great for use with HTML templates

ES5:

var html = '
' + '

Hello ' + str + '!

' + '
';

becomes

ES6:

const html = `

Hello ${str}!

`;

Using Template Strings

const message = `User ${name} scored ${score} on the exam`;

 

  • Use backticks (` `) around the string
  • Use ${ } around any variable or expression
  • Work well with ternary operators, for example
    ${ userIsYoungerThan21 ? serveGrapeJuice() : serveWine() }

 

const message = `User ${name} ${score >= 60 ? 'passed' : 'failed'} the exam`;

Default Parameter Values

Using ES5, we could establish default parameter values, but there were some flaws
View CodePen »

ES5:

function makeRequest(url, timeout, callback) {
  timeout = timeout || 2000;
  // what if timeout is 0?
  callback = callback || function() {};
  callback();
}

becomes

function makeRequest(url, timeout, callback) {
  timeout = (typeof timeout !== 'undefined') ? timeout : 2000;
  callback = (typeof callback !== 'undefined') ? callback || function() {};
  callback();
}

ES6:

function makeRequest(url, timeout = 2000, callback = () => {}) {
  callback();
}
It's beautiful

It's beautiful

Calling functions with default parameters

Given the following function:

function makeRequest(url, timeout = 2000, callback = () => {}) {
  callback();
}

Only url is required. The following calls all work:

makeRequest('/api');
				
makeRequest('/api', 500);

makeRequest('/api', 0, requestData => updateDatabase(requestData));

makeRequest('/api', undefined, requestData => updateDatabase(requestData));

( 3 )New functionality for working with arrays and objects

Destructuring Objects

Unpack properties from objects into distinct variables

ES5:

var person = {
  name: 'Whitney',
  age: 38
};
		
var name = person.name;
var age = person.age;
		
console.log(name, age); // Whitney 38

becomes

ES6:

const person = {
  name: 'Whitney',
  age: 38
};
		
const { name, age } = person;
console.log(name, age); // Whitney 38
  • Left-hand side of the equal sign (=)
    A comma-separated list of the object's keys you'd like to unpack, wrapped in { }
  • Right-hand side of the equal sign (=)
    The object you're destructuring

Destructuring Arrays

Array destructuring operates on positions within an array rather than any named properties

ES5:

var colors = ['red', 'green', 'blue'];
		
var first = colors[0];
var second = colors[1];
var third = colors[2];
		
console.log(first, second, third);
// red green blue

becomes

ES6:

const colors = ['red', 'green', 'blue'];
		
const [ first, second, third ] = colors;
		
console.log(first, second, third);
// red green blue
  • Left-hand side of the equal sign (=)
    A comma-separated list of the values you'd like to unpack, wrapped in []
  • Right-hand side of the equal sign (=)
    The array you're destructuring

Array Helpers

Tons of new methods that can be applied to arrays

Array Helper Use it to... Returns
✔️ arr.forEach((element, index, array) => { }); loop through elements in an array undefined
arr.every((element, index, array) => { }); check if every element passes a test true||false
arr.some((element, index, array) => { }); check if some (at least 1) arr elements pass a test true||false
arr.filter((element, index, array) => { }); create a new array by filtering the original array elements Array
✔️ arr.map((element, index, array) => { }); create a new array by modifying the original array elements Array
✔️ arr.find((element, index, array) => { }); find the first element that passes a test 1 element
arr.findIndex((element, index, array) => { }); find the index of the first element that passes a test 1 element
✔️ arr.reduce((calculatedValue, element, index, array) => { }, initialValue); pass in an initialValue and modify it according to the current element value 1 reduced value

Array Helpers

Moving away from for loops

  • Easier for other devs to immediately read and understand
  • Encourage functional programming
  • More compact — why write more code?
  • More maintainable and scalable

forEach

Array Helper Use it to... Returns
arr.forEach((element, index, array) => { }); loop through elements in an array undefined

ES5: for loop

var names = ['Morgan', 'Taylor', 'Lesley'];

for (var i = 0; i < names.length; i++) {
  console.log(names[i]);
}

ES6: forEach

const names = ['Morgan', 'Taylor', 'Lesley'];

names.forEach(function(name, index, array) {
  console.log(name);
});

View CodePen »

forEach

arr.forEach(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
  numbers.forEach(function(number, index, array) {
  console.log(number > 50); // can you get this on one line?
});

The iterator function runs once for each element in the array

forEach diagram

map

Array Helper Use it to... Returns
arr.map((element, index, array) => { }); create a new array by modifying the original array elements Array

 

You can assign the resulting array to a variable:
const modifiedArr = arr.map(iteratorFunction);

ES5: for loop

var numbers = [2, 6, 10];
var halvedNumbers = [];

for (var i = 0; i < numbers.length; i++) {
  halvedNumbers.push(numbers[i] / 2);
}

console.log(halvedNumbers); // 1, 3, 5

ES6: map

const numbers = [2, 6, 10];

const halvedNumbers = numbers.map(number => number / 2);

console.log(halvedNumbers); // 1, 3, 5

View CodePen »

No need to create an empty array first! 🎉

map

arr.map(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
const decrementedNumbers = numbers.map(number => number - 1);
console.log(decrementedNumbers); // [ 122, 499, -51, 81, 7 ]

The iterator function runs once for each element in the array

Be sure to return a value each iteration!

map diagram

find

Array Helper Use it to... Returns
arr.find((element, index, array) => { }); find the first element that passes a test 1 element

const matchingObject = arr.find(iteratorFunction);

ES5: for loop

var jobs = [
  { title: 'Electrician' },
  { title: 'Developer' },
  { title: 'Barista' }
];
var devJob;
for (var i = 0; i < jobs.length; i++) {
  if (jobs[i].title === 'Developer') {
    devJob = jobs[i];
	break;
  }
}
console.log(devJob); // { title: 'Developer' }

ES6: find

const jobs = [
  { title: 'Electrician' },
  { title: 'Developer' },
  { title: 'Barista' }
];
const devJob = jobs.find(job => job.title === 'Developer');
console.log(devJob); // { title: 'Developer' }

CodePen Example »

find

arr.find(iteratorFunction)

const jobs = [
  { title: 'Electrician' },
  { title: 'Developer' },
  { title: 'Barista' }
];
const devJob = jobs.find(job => job.title === 'Developer');
console.log(devJob); // { title: 'Developer' }

Runs until the iterator function returns true. When it does, the element at that index is returned.

find diagram

find() Practical Example

Single-page web apps

The find helper in a single-page web app

reduce

Array Helper Use it to... Returns
arr.reduce((calculatedValue, element, index, array) => { }, initialValue); pass in an initialValue and modify it according to the current element value 1 reduced value

const reducedValue = arr.reduce(iteratorFunction, initialValue);

ES5: for loop

var numbers = [2, 6, 10];

var sum = 0;
for (var i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}

console.log(sum); // 18

ES6: reduce

const numbers = [2, 6, 10];

const sum = numbers.reduce(function(currentSum, number) {
  return currentSum + number;
}, 0);

console.log(sum); // 18

View CodePen »

reduce in action

arr.reduce(iteratorFunction, initialValue);

const numbers = [1, 5, 10];

const sum = numbers.reduce(function(calculatedValue, number) {
  return calculatedValue + number;
}, 0); // 0 is the initialValue

console.log(sum); // 16

Map and Reduce

A Sandwich Metaphor

Map and Reduce with sandwiches

( 4 )A built-in helper for making AJAX requests

Fetch

The fetch() helper is used for AJAX requests

The initial return value is the Response object; use chaining and the .json() method to get the JSON you need

fetch('http://json.com')
  .then(serverResponse => serverResponse.json())
  .then(json => console.log(json))
  .catch(err => console.log(err));

Let's take a look »

( 5 )Encourage the ✨powers✨ of object-oriented programming

Classes

ES5:

function Vehicle(type) {
  this.type = type;
}
			
Vehicle.prototype.logType = function() {
  console.log(this.type);
};
			
var car = new Vehicle('car');
car.logType(); // 'car'
			
console.log(car instanceof Vehicle); // true
console.log(car instanceof Object); // true

called "creating a custom type"

ES6:

class Vehicle {
  constructor(type) {
    this.type = type;
  }
			
  logType() {
    console.log(this.type);
  }
}
const car = new Vehicle('car');
car.logType(); // 'car'
			
console.log(car instanceof Vehicle); // true
console.log(car instanceof Object); // true

 

You don't need commas between the elements of a class

Derived Classes

Derived classes: Classes that inherit from other classes

Within the derived class's class {} definition, use the extends keyword to specify the base class. Then access the base class constructor by calling super().

class Rectangle {
  constructor(length, width) {
    this.length = length;
    this.width = width;
  }
			
  getArea() {
    return this.length * this.width;
  }
}
class Square extends Rectangle {
  constructor(length) {
    super(length, length); // calls the base class constructor
  }
}
			
const square = new Square(5);
console.log(square.getArea()); // 25

Let the coding begin!

Check the "Workshop Instructions" section of the printed handout, or go to http://tinyurl.com/wwc-activity

 

Remember:

  • We are here for you!
  • Every question is important
  • Help each other
  • Have fun

Additional Resources

Transpiling = Transformation + Compiling

Transpiling

Before: ES6

const getMessage = () => 'Hello World';

After: ES5

Waiting...

 

Additional Resources

Books

 

Keeping in the Loop
  • 2ality
  • PonyFoo
  • Medium and YouTube channels
  • Meetups: Women Who Code, Node.JS Boston, Tech Ladies, BostonJS, Girl Develop It, etc.

Questions

?

linkedin.com/in/lizhelene