Notesheet: ES6/ES2015+ (JavaScript)

Status: Work in Progress. Updated: 3 February 2020


Arrow Functions

  • Shorthand format for writing traditional functions.
  • Denoted by what some people call a “fat arrow”: =>
  • Removes the “function” keyword and often the “return” keyword and function block curly braces (“{” and “}”)
  • Formats can include:
    • () => { return …..; }
    • {x} => (return x+1; }
    • (x, y, z) => { if (x == 1} { return y; } else { return z; } }
    • Class.someFunction(x => x + 1);
    • var myFunction = x => x + 1;
    • var myFunction = x => { return x + 1; };
  • https://caniuse.com/#search=arrow%20functions

 

Traditional JavaScript function:

function sumOfNumbers(number1, number2)
{
  return number1 + number2;
}

 

ES2015 arrow function equivalent:

var sumOfNumbers = (number1, number2) => { var sum = number1 + number2; return sum * 2; }

 


Classes

Traditional “class” using a function

function Person(firstName, lastName)
{
  this.FirstName = firstName;
  this.LastName = lastName;

  this.GetFullName = function()
  {
    return this.FirstName + " " + this.LastName;
  }
}
var person = new Person("Bob", "Smith");
person.GetFullName();

ES2016 Class

class Person
{
  constructor(firstName, lastName) 
  {
    // FirstName and LastName properties are automatically created.
    this.FirstName = firstName;
    this.LastName = lastName;
  }
  
  /*
  *	Method to return the full name.
  */
  GetFullName() 
  {
    return this.FirstName + " " + this.LastName;
  }
}
var person = new Person("Jason", "Snelders");
person.GetFullName();

 

You can also define a property on the class like pre-ES2015, as in the following example.
Define it in the constructor() and you don’t have to pass a constructor parameter in to do anything with it (just give it a default value).
Then you can use the special “set” and “get” function to access it later. Or access it directly.
In this example “_displayName” is the defined property in question.
NOTE: You can’t use the same name for a property as the “set”/”get” function, so a good convention is to prefix the property with an underscore (“_”).
It’s still publicly accessible but represents a logically private property.

 

class User {
  constructor(username, password, loggedIn = false)
  {
    this.username = username;
    this.password = password;
    this.loggedIn = loggedIn;
    
    this._displayName = "";
  }

  set displayName(name) { this._displayName = name; }
  get displayName() { return this._displayName; }
  
  show()
  {
    console.log(`Username: ${this.username}`);
    console.log(`Password: ${this.password}`);
    console.log(`Logged In: ${this.loggedIn}`);
    console.log(`Display Name: ${this._displayName}`);
  }
}

// Create an object from the Class
const jason = new User("jason", "test123");

console.log("Show(1)...");
jason.show();

jason.displayName = "Jason Snelders";

console.log("Show(2)...");
jason.show();

jason._displayName = "Directly set _dislayName";

jason._displayName = "The Jason";

console.log("Show(3)...");
jason.show();

console.log(`Read directly from jason.displayName = '${jason.displayName}'`);

See it in action (open the Console) at https://codepen.io/jsnelders/pen/abOOGVe.

 


Define Variables: ‘let’ and ‘const (vs ‘var’)

  • Traditionally we only had ‘var’ keyword to define a variable.
  • ‘let’ is like ‘var’ but the variable is constrained to block scope – i.e. within the curly braces (“{” and “}”) it is defined between. For example, if() and for() statements.
  • ‘const’ is a constant with a value that is set at the time it is defined and that cannot be changes later.
    • The exceptions are:
      • arrays: values/elements within the array can be added and remove (but the whole array cannot be re-assigned).
      • objects: values of individual properties can be update, but the whole object cannot be reassigned.
  • https://caniuse.com/#search=let
  • https://caniuse.com/#feat=const

 

Simple var, let and const

var aVariable = "One";
const aConst = "Two"
let aLet = "Three"

console.log(aVariable);  // Display "One"
console.log(aConst);     // Display "Two"
console.log(aLet);       // Display "Three"
  
aConst = "Four";	 // No. You cannot change a constant. Will produce a "Assignment to constant variable" error.
  
aLet = "Five";
console.log(aLet); // Now displays "Five"

 

Scoping ‘let’

if (aVariable == "One")
{
  // A new variable 'aLet' is defined within only within the block scope of the if() statement.
  // It will not affect the value of 'aLet' defined above.
  let aLet = "New Let";
  
  console.log(aLet);	// Display "New Let".
}

// We cannot see the 'aLet' defined in the if() statement 
// so we display the value of 'aLet' defined in the out scope 
// (i.e. the original aLet).
console.log(aLet);	// Display "Three"

 

Arrays as constants

const array = [1, 2, 3];
  
console.log(arrayToString(array));  //Display 1,2,3
  
// We cannot do this - re-assign the array.
//array = [4,5,6];	
  
// But we can still add/remove individual items from the array.
array.push(7);
  
console.log(arrayToString(array));   // Display 1,2,3,7

 

Objects as constants

const person = {
  name: "Jason",
  age: "Old"
}
  
console.log(person.name);   // Display "Jason"
  
// We cannot re-assign the object (like the array).
//person = { name: "Bruce" };
  
person.name = "Bruce";
  
// But we can update individual properties on the object.
console.log(person.name);   // Display "Bruce"

 

Example: using ‘let’ in counters to preserve existing variables.

//-- Traditional variables
var i = "Cat";
  
console.log(i);   // Display "Cat"
  
for (var i = 0; i<=5; i++)
{
  // Do something
}
  
The original declaration of 'i' was re-purposed for the counter.
console.log(i);   // Display "5".
  

//-- ES2015 example with 'let'
  
let i = "Cat";
  
console.log(i);   // Display "Cat"
 
for (let i = 0; i<=5; i++)
{
  // Do something
  console.log(i);   // Will update and display increasing from "1" to "5" with each loop.
}
  
// The original definition of 'i' in the outer scope (outside the for() loop) is preserved.
console.log(i);   // Display "Cat".

 


Default Function Parameter Values

  • A default value can be specified on parameters in the definition (signature) of a function.
  • If the function is called and that parameter is missed, the default value will be used.
  • If a value is passed in to the parameter then the supplied value is used.
  • Parameters without default values must appear before the first default parameter.
    • e.g. This is wrong myFunction(param1, param2 = ‘some value’, param3) because param3 does not have a default value but it appears after a parameter that does have a default.
    • Why? Consider calling the function: myFunction(‘first value’, , ‘third value);. Having a blank parameter when calling a function is not not valid code.
  • https://caniuse.com/#feat=mdn-javascript_functions_default_parameters

 

Traditional function

function aboutMe(firstName, lastName, location)
{
  return "My name is " + firstName + " " + lastName + ". I come from " + location + ".";
}

// This will error because the 'location' parameter is not passed in.
var result = aboutMe("Jason", "Snelders");

 

ES2015 function with a default parameter value

function aboutMe(firstName, lastName, location = 'Woop Woop')
{
  return "My name is " + firstName + " " + lastName + ". I come from " + location + ".";
}

// The default value of "Woop Woop" will be used for 'location'.
var result1 = usingDefaultParameters("Jason", "Snelders");
console.log(result1);   // Display: My name is Jason Snelders. I come from Woop Woop.
  
// The provided value of "Melbourne" will be used for 'location'.
var result2 = usingDefaultParameters("Jason", "Snelders", "Melbourne");
console.log(result2); // Display: My name is Jason Snelders. I come from Melbourne.

 


Reset Operator in Function Parameters

Example function definition:

function myFunction(myName, ...roles) 
{ 
  console.log(roles); 
}

The 3 dots preceding ‘roles’ (…roles) is the rest operator.

So if we call the function:

myFunction("Jason", "Developer", "Architect", "Lead", "Consultant");

The console output of ‘roles’ from that function will be an array:

["Developer", "Architect", "Lead", "Consultant"]

 

 


Template Literals

  • A string surrounded by back ticks  (`).
  • The string can be split over multiple lines.
  • You can embed literal references to variables in the same scope that are replaced when the string is “rendered” (aka “variable/expression replacement” or “string interpolation”).
  • A good option for “+” operator based string concatenation.
  • Any expression in JavaScript can be used within the curly braces (“{…}”).
  • https://caniuse.com/#feat=template-literals
var name = "Jason";
var statement = `My name is ${name}`;

console.log(statement);   // Displays "My name is Jason"

var multilineStatement = `My name is ${name}
and I am a software developer`;

console.log(multilineStatement);   // Displays "My name is Jason
                                                and I am a software developer".

Alternative to concatenation:

Old style:

var createUrl = function(domain, path) { return "https://" + domain + "/" + path;  }

With string literals:

var createUrl = function(domain, path) { return `https://${domain}/${path}`;  }

 

Other expression examples

`2 + 2 = ${2 + 2}`
`It is ${new Date().getHours() < 12 ? 'AM' : 'PM' }`

 


Spread Operator (…)

Example:

const myArray = [1, 2, 3];
console.log(...myArray); // Displays "1 2 3" (the individual values of the array).

Example scenario:

function add = (a, b, c) => a + b + c;
const myArray = [1, 2, 3];
add(...myArray);  // Returns "7"

Using the spread operator splits myArray and assigned each of the value to the arguments of the add() function we are calling.

Another example – add arrays together:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [...array1, ...array2, 10];

This will create an array that looks like [1,2,3,4,5,6,10].

Similar Example with objects:

const obj1 = { name: "Jason" };
const obj2 = { location: "Melbourne" };
const obj3 = { ...obj1, ...obj2, "Learning": true };

We end up with an obj3 that l looks like:

const obj3 = { name: “Jason”, location: “Melbourne”, “Learning”: true };

And we can change obj1.name = “Bruce” and obj3.name remains as “Jason”.


Tagged Templates

  • Function that take a mix of string and variables, then formats and returns them based on some rules you apply.

 


Modules (“import” and “export”)

  • Code that can be written in one file and used in another (outside of the global scope).
  • Keywords “import” and “export”.
  • The name of the module is (by default) taken from the name of the .js file.
  • Each function we want to make available to other files is included in an “export”.
  • To use exported functions in other files we use the “import” keyword and reference the file to import from.
  • By default all exported functionality is imported, or we specify just the functions we want.
  • You can export a single default function (“export defailt …”) from a module and when importing you can give it any name you want.
  • NOTE: As of early 2020 modules is not handled well natively in Node (and I presume browsers) so you will need to use bundlers to get it working.

 

 


Other features to create examples for:

  • 22:34 Extended Literals
  • 24:42 Extended Object Literals
  • 28:18 Destructuring Assignment
  • Promises
  • async/await

 

 

 


Learning Resources