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