Getting Started with ES6 and ES7 JavaScript

ES6 and ES7 Intro Image

Class 2

Today's Topics

  • Review at-home challenge from last class
  • Arrow Functions
  • Arrow Functions and this
  • Array Helpers
  • Altering Arrays

Review

Fruit Basket

var fruit = 'apple';

(function basket(){
    var fruit = 'banana';
    console.log(fruit);
})();

console.log(fruit);

var fruitBasket = {
    fruit: 'mango',
    getFruit: function(){
      console.log(fruit);
      fruit = 'orange';
    }
};
fruitBasket.getFruit();
console.log(fruit);
View on CodePen »

What would the following output to the console and why?

Answer:

banana
apple
apple
orange
Understand JavaScript's this with clarity, and master it »

Arrow Functions

Arrow Functions

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)

Activity

Writing arrow functions

Refactor the following code to use arrow functions.

Activity 1

See the Pen Arrow Function Exercise #1 by Liz Shaw (@anythingcodes) on CodePen.

Activity 2

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

Arrow Functions and this

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

JavaScript `this` tweet by Ben Halpern

What is this problem?

Let's take a look

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

Activity

Fixing this scoping with arrow functions

See the Pen Arrow Functions Activity by Liz Shaw (@anythingcodes) on CodePen.

View Solution

Array Helpers

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

Activities

Using the forEach Helper

Modify the code between
// [START] your code here and // [END] your code here

Activity 1

See the Pen ES6 Lesson 1: forEach #2 by Liz Shaw (@anythingcodes) on CodePen.

Activity 2

See the Pen ES6 Lesson 1: forEach #1 by Liz Shaw (@anythingcodes) on CodePen.

every

Array Helper Use it to... Returns
arr.every((element, index, array) => { }); check if every element passes a test true||false

ES5: for loop

var students = [
  { name: 'Morgan', present: true },
  { name: 'Sam', present: false },
  { name: 'Taylor', present: true }
];
var allPresent = true;
for (var i = 0; i < students.length; i++) {
  if (!students[i].present) {
    allPresent = false;
    break;
  }
}
console.log(allPresent); // false

ES6: every

const students = [
  { name: 'Morgan', present: true },
  { name: 'Sam', present: false },
  { name: 'Taylor', present: true }
];
const allPresent = students.every(student => student.present);
console.log(allPresent); // false

View CodePen »

every

arr.every(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
const allLargerThan50 = numbers.every(number => number > 50);
console.log(allLargerThan50); // false

Runs until the iterator function returns false, in order to check that every element passes a test

every diagram

some

Array Helper Use it to... Returns
arr.some((element, index, array) => { }); check if some (at least 1) arr elements pass a test true||false

ES5: for loop

var students = [
  { name: 'Morgan', present: true },
  { name: 'Sam', present: false },
  { name: 'Taylor', present: true }
];
var somePresent = false;
for (var i = 0; i < students.length; i++) {
  if (students[i].present) {
    somePresent = true;
    break;
  }
}
console.log(somePresent); // true

ES6: some

const students = [
  { name: 'Morgan', present: true },
  { name: 'Sam', present: false },
  { name: 'Taylor', present: true }
];
const somePresent = students.some(student => student.present);
console.log(somePresent); // true

View CodePen »

some

arr.some(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
const someLargerThan50 = numbers.some(number => number > 50);
console.log(someLargerThan50); // true

Runs until the iterator function returns true (i.e. when some elements pass a test)

some diagram

 

Activity

Using the every and some helpers

Activity 1

See the Pen every() and some() activity by Liz Shaw (@anythingcodes) on CodePen.

View Solution

Activity 2

See the Pen every() and some() activity #2 by Liz Shaw (@anythingcodes) on CodePen.

View Solution

filter

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

const filteredArr = arr.filter(iteratorFunction);

ES5: for loop

var users = [
  { username: 'ryan10', active: true },
  { username: 'morgan', active: false }
];
var activeUsers = [];
for (var i = 0; i < users.length; i++) {
  if (users[i].active) {
    activeUsers.push(users[i]);
  }
}
console.log(activeUsers);

ES6

const users = [
  { username: 'ryan10', active: true },
  { username: 'morgan', active: false }
];
const activeUsers = users.filter(user => user.active);
console.log(activeUsers);

CodePen example with non-boolean »

filter

arr.filter(iteratorFunction)
const numbers = [123, 500, -50, 82, 8];
const numbersLargerThan50 = numbers.filter(number => number > 50);
console.log(numbersLargerThan50); // [ 123, 500, 82 ]

Only the elements that return true are included in the resulting array

filter diagram

 

Activities

Using the filter helper

Activity 1

See the Pen ES6 Lesson 1: filter #2 by Liz Shaw (@anythingcodes) on CodePen.

Activity 1 Tip: A number is even if
number % 2 === 0

View Solution

Activity 2

See the Pen ES6 Lesson 1: filter #1 by Liz Shaw (@anythingcodes) on CodePen.

View Solution

 

filter() Practical Example

Filtering API Responses

The data relationship between comments and posts - step 1
The data relationship between comments and posts - step 2
The data relationship between comments and posts - step 3
The data relationship between comments and posts - step 4
The data relationship between comments and posts - step 5
The data relationship between comments and posts

API Response Example »
CodePen Example »

Activities

Filtering API responses

Activity 3

See the Pen ES6 Lesson 1: filter #3 by Liz Shaw (@anythingcodes) on CodePen.

View Solution

Tip: Try to use more than one array helper. Are there any other ES6 tricks you could use to clean up this code?

 

At-Home Challenge: Implement a reject function

function reject(array, iteratorFunction) {
  // your code here
}

Hint: You may use filter.

Fork this CodePen for some starter code.

Reject should work opposite to filter; if a function returns true, the item should not be included in the new array, for example:
 

const numbers = [ 5, 10, 15, 17, 18, 20 ];
const lessThanEighteen = reject(numbers, number => number >= 18);
console.log(lessThanEighteen);
// returns [ 5, 10, 15, 17 ];

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

Activities

Using the map Helper

Activity 1

See the Pen ES6 Lesson 1: map #2 by Liz Shaw (@anythingcodes) on CodePen.

Activity 2

See the Pen ES6 Lesson 1: map #1 by Liz Shaw (@anythingcodes) on CodePen.

At-Home Challenge: Implement a pluck function

function pluck(array, property) {
  // your code here
}

Hint: Access a property on an object by using square bracket notation. For example:
 

const animal = { type: 'Dinosaur', status: 'Extinct' };
animal['type']; // returns 'Dinosaur'

Pluck should accept an array and a string representing a property name and return an array containing that property from each object, for example:
 

const cats = [ { name: 'Colonel Meow' }, { name: 'Lil Bub' }, { name: 'Grumpy Cat' }];

pluck(cats, 'name');
// returns ['Colonel Meow', 'Lil Bub', 'Grumpy Cat'];

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

Activities

Using the find helper

See the Pen the find() array helper by Liz Shaw (@anythingcodes) on CodePen.

View Solution

At-Home Challenge: Write a findWhere function

Often we need to find an object with a given property and value. Write a findWhere function that accepts two parameters, the array and the criteria as an object, and returns the matching object. You may assume that the criteria is one key-value pair. Fork this CodePen for some starter code.

Hint: Use Object.keys(criteria)[0] to figure out the name of the property on the object. For example, Object.keys({ type: 'marsupial' }) would return 'type'. You could then check to see if a given element in the array had a property equal to the criteria's value with something like element[property] === criteria[property].

The following code ...

const animals = [
  { id: 0, name: 'iguana', type: 'reptile' },
  { id: 1, name: 'cardinal', type: 'bird' },
  { id: 2, name: 'platypus', type: 'marsupial' },
  { id: 3, name: 'frog', type: 'amphibian' }
];

findWhere(animals, { type: 'marsupial' });

would return one object ...

{ id: 2, name: 'platypus', type: 'marsupial' }

At-Home Challenge: Write a filterWhere function

Write a filterWhere function that accepts two parameters, the array and the criteria as an object, and returns an array of matching objects. All of the criteria must match for an object to be included in the resulting array. Assume that multiple criteria can be included, for example:

filterWhere(animals, { name: 'kangaroo', type: 'marsupial' })

Fork this CodePen for some starter code.

Hint: Although you may need different array helpers for this challenge, we recommend warming up with the previous slide's findWhere challenge first.

The following code ...

const animals = [
  { id: 0, name: 'iguana', type: 'reptile' },
  { id: 1, name: 'cardinal', type: 'bird' },
  { id: 2, name: 'platypus', type: 'marsupial' },
  { id: 3, name: 'kangaroo', type: 'marsupial' },
  { id: 4, name: 'frog', type: 'amphibian' }
];

filterWhere(animals, { type: 'marsupial' });

would return an array of ...

[
  { id: 2, name: 'platypus', type: 'marsupial' },
  { id: 3, name: 'kangaroo', type: 'marsupial' }
]

findIndex

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

const matchingIndex = arr.findIndex(iteratorFunction);

ES5: for loop

var numbers = [ 25, 30, 35, 40, 45 ];
var firstIndex;
for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > 33) {
    firstIndex = i;
    break;
  }
}
console.log(firstIndex); // 2

ES6: findIndex

const numbers = [ 25, 30, 35, 40, 45 ];
const firstIndex = numbers.findIndex(number => number > 33);
console.log(firstIndex); // 2 (the location of 35)

CodePen Example »

findIndex

arr.findIndex(iteratorFunction)

const numbers = [ 25, 30, 35, 40, 45 ];
const firstIndex = numbers.findIndex(number => number > 33);
console.log(firstIndex); // 2 (the location of 35)

Just like find(), runs until the iterator function returns true. When it does, that index is returned.

The findIndex array helper

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

// when iteratorFunction is a reference:
arr.reduce(iteratorFunction, initialValue);

// or when iteratorFunction isn't a reference:
arr.reduce((calculatedValue, element, index, array) => { }, initialValue);

 

reduce is slightly different from the other array helpers because it takes two parameters:

  1. iteratorFunction
    • The iterator function requires a calculatedValue parameter, which is modified each time and returned each iteration
  2. initialValue — used during the first iteration to calculate the next iteration's calculatedValue

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

Activities

Using the reduce helper

Activity 1
Activity 2

Map and Reduce

A Sandwich Metaphor

Map and Reduce with sandwiches

reduce

Use it creatively and ace your next interview

  • Write a function, isBalanced, to determine if an expression's parentheses are balanced. For example, (())()() would be balanced, while ()(() and )( would not.

ES5 🤔❓

var parens = '(())()()';
var parensFalse = '()(()';
var parensFalse2 = ')(';

console.log(isBalanced(parens)); // true
console.log(isBalanced(parensFalse)); // false
console.log(isBalanced(parensFalse2)); //false

function isBalanced(expression) {
  var retVal = 0;
  var chars = expression.split('');
  for (var i = 0; i < chars.length; i++) {
    var char = chars[i];
    if (retVal >= 0) {
      if (char === '(') {
        retVal++;
      } else if (char === ')') {
        retVal--;
      }
    }
  }
  return retVal === 0;
}
View on CodePen »

ES6 💪

We can do better!

Let's head to CodePen »

 

View Solution »

At-Home Challenge: Implement a unique function

function unique(array) {
  // your code here
}

Hint: Use reduce and find.

Write a function that will remove duplicate values from an array. For example:
 

const arr = [ 5, 5, 10, 10, 15, 20, 20 ];
const uniqueArr = unique(arr);
console.log(uniqueArr);
// returns [ 5, 10, 15, 20 ];

Quiz

Which array helper would be most suitable for each situation? (forEach, every, some, filter, map, find, or reduce)

  1. You need to check if all elements in an array are integers.
  2. You have an array of blog posts and need to output each post on the page.
  3. You need to check if an array has at least one element that isn't null.
  4. You have an array of expenses and need to calculate your total expenses last month.
  5. You need a new array to store the square root of each item in an existing array.
  6. You have an array of computers, but only need computers with more than 16 GB of RAM.
  7. You have an array of blog posts, and need to retrieve one post by its ID.

Food for Thought 🤔

Array helpers are often used in single-page web apps, like Gmail. Which array helper would be most suitable for each situation? (forEach, every, some, filter, map, find, or reduce)

const bindings and reassignments

Altering Arrays

Altering Arrays

New methods that alter existing arrays

 

Array Method Use it to... Returns
arr.fill((value, startIndex, endIndex) => { }); fill all the elements of an array from start index to end index with value the modified array
arr.copyWithin((targetIndex, startIndex, endIndex) => { }); copy part of an array to another location in the same array the modified array

fill

Array Method Use it to... Returns
arr.fill((value, startIndex, endIndex) => { }); fill all the elements of an array from start index to end index with value the modified array
  • If no startIndex or endIndex is given, the whole array is filled with the same value

ES5: for loops

var numbers = [1, 2, 3];

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

console.log(numbers); // [4, 4, 4]


var numbers2 = [1, 2, 3];
var startIndex = 1;
var endIndex = 2;
for (var j = 0; j < numbers2.length; j++) {
  if (j >= startIndex && j < endIndex) {
    numbers2[j] = 4;
  }
}

console.log(numbers2); // [1, 4, 3]

ES6: fill

const numbers = [1, 2, 3];
const numbers2 = [1, 2, 3];

numbers.fill(4);
console.log(numbers); // [4, 4, 4]

numbers2.fill(4, 1, 2);
console.log(numbers2); // [1, 4, 3]

copyWithin

Array Method Use it to... Returns
arr.copyWithin((targetIndex, startIndex, endIndex) => { }); copy part of an array to another location in the same array the modified array
  • If no startIndex or endIndex is given, the whole array is filled with the same value

 

const spells = ['hocus', 'pocus', 'wingardium', 'leviosa'];

spells.copyWithin(2, 0);
console.log(spells);
// ['hocus', 'pocus', 'hocus', 'pocus']

Questions

?