ES5 vs ES6

Learning Goals

  • Compare ES5 vs. ES6
  • Understand and explain prototypal inheritance in JavaScript


  • Scope Where variables and functions are accessible
  • Prototypal Inheritance Inheritance by means of delegating message passing through a chain of objects (aka prototypes)

Warm Up

  • What do you think of when you hear the word prototype?
  • When have you used prototypes in your code?
  • Do you prefer template literals to concatenation? Why or why not?

The differences between ES5 and ES6

Up until now, you’ve mostly been writing ECMAScript 5. (You can read more about ECMAScript here.)

ES5 is comfortable and familiar, but we ES6 gives us a lot of great new features, which we’ll start learning about here.


Block Scope

We’re familiar with global and function scope. cope is literally the scope in which a variable or value can be accessed.

We already know that variables declared (using the keyword var) inside of a function will remain scoped to that function. In other words, it won’t be accessible outside of the function.

ES6 gives us two new variable keywords: let and const. These two variable keywords introduce block scope.

What is a block? The most common ones that you will be familiar with are if statements and for loops. You can read more about block statements here.

Turn and Code

With a partner, consider the example below. What is happening within the body of our for loop? What will be returned? Why?

// es5 block scope
var callbacks = [];

for (var i = 0; i <= 2; i++) {

    callbacks[i] = function () { 
      return i * 2; 

callbacks[0](); // What will this return?
callbacks[1](); // What will this return?
callbacks[2](); // What will this return?

Previously, when we wanted a variable to remain scoped to a block, we had to wrap the contents of the block in a function.

And here’s how we would do it with ES6 syntax:

// es6 block scope
var callbacks = []

for (let i = 0; i <= 2; i++) {
  callbacks[i] = function () {
    return i * 2 


callbacks[0]() === 0
callbacks[1]() === 2
callbacks[2]() === 4

The major differences are:

  • using the keyword let instead of var in the for loop, which will remain scoped to that block
  • not needing to wrap the contents of the loop in a function, because the i is no longer referencing a variable that has been scoped globally

The differences between let and const:

Variables declared with let can be reassigned, whereas variables declared with const cannot.

If an array or object is declared using the keyword const, the contents of that array or object can be changed, but that variable name will always point to that same piece of memory.

Turn and Talk

What are var, let, and const similar? How are they different?

Arrow Functions

ES6 gives us another way to write functions. They’re called arrow functions because they have an arrow in them. Neat!

Let’s look at the synctactic differences first:

Say we have an array of even numbers: var evens = [0, 2, 4, 6, 8];

We can map over that array to create new arrays of odds, pairs, and nums:

// es5 syntax examples
var odds = (v) { 
  return v + 1; 

var pairs = (v) {   
  return { even: v, odd: v + 1 }; 

var nums = (v, i) { 
  return v + i; 

var fives = [];
nums.forEach(function (v) {
  if (v % 5 === 0) {

Compare that to arrow function syntax:

var odds = => 
  v + 1

var pairs = => 
  ({ even: v, odd: v + 1 })

var nums =, i) => 
  v + i

var fives = [];
nums.forEach(v => {  
  if (v % 5 === 0) {

Here are some features arrow functions give you:

  • implicit return
    • the curly braces and keyword return can be eliminated and the remaining expression will be evaluated and returned
    • only make use of this when a single expression is written
    • multiple lines or expressions in an arrow function require the curly braces and the keyword return
  • return an object
    • surround the object with parentheses
    • you can still also use syntax from ES5 instead of parentheses if more semantic/readable
  • drop the parentheses around a single parameter
    • if using multiple parameters or no paremeters, the parentheses must be used

To name an arrow function, you must save it as a variable.

// es5 syntax
function sayHi() {

// es6 syntax
const sayHi = () => console.log('Hi!');

Turn and Talk

What are the benefits of using arrow functions over function declarations?

Handling Parameters

ES6 gives us more ways to handle parameters.

Default parameters:

If you want to give some parameters default values, ES6 allows you to do that with much less syntax than ES5.

Consider the following code:

// es5
function f (x, y, z) {
    if (y === undefined) {
        y = 7;
    if (z === undefined) {
        z = 42;
    return x + y + z;

f(1) // 50

// es6
function f (x, y = 7, z = 42) {
    return x + y + z

f(1) // 50

Spread operator:

The spread operator has many more applications.

var arr = [4, 5, 6];

// es5
var completeArr = [1, 2, 3].concat(arr); // [1, 2, 3, 4, 5, 6]

// es6
var completeArr = [1, 2, 3, ...arr]; // [1, 2, 3, 4, 5, 6]

The spread operator took the individual values from the array and added them into the new array.

var string = 'hello';

// es5
var characters = string.split(''); // ['h', 'e', 'l', 'l', 'o']

// es6
var characters = [...string]; // ['h', 'e', 'l', 'l', 'o']

In this case, the split method is not terribly complex, but using the spread operator makes the code more readable at a glance; you can see that the result is an array.


  • What new changes did ES6 bring in so far as the following:
    • scope
    • functions
    • classes
  • What is prototypal inheritance?

Additional Resources:

Lesson Search Results

Showing top 10 results