3D Gallery with Great Artwork Imagine Logo with Three Colors Beach Cabin 3D Android Tablet with Different Screens Studio Apartment Red Figured Greek Vase on Blue Background Silver and Gold Flashlight Lake on Fire

JavaScript: Advanced

Page 7

Template Literals, Promises, Closures, Arrow Functions

Introduction Template Literals Promises Closures Arrow Functions Rest Parameters Combine Arrow, Rest, Array Reduce Strict Mode Modules Simple Module Export Simple Module Import Class: Module, Import, Event Listener Tap a Module Button! Summary

Introduction

Learn many new or advanced JavaScript techniques including template literals, template literals with expressions, promises, closures, arrow functions, rest parameters, strict mode, modules including simple imports with exports, and class imports with exports. We'll also combine rest parameters with arrow functions.

Template Literals

Template Literal Substitution

A template literal with substitution allows developers to substitute variable values within brackets. A template bracket begins with ${ and ends with }.

Insert strings sBreed and sType into the string text, within brackets ${..}. The return value equals Animal: Savannah, Cat.. Click the box to see the result, below. The following function, fTemplate() includes the code to return a string from a template literal.

function fTemplate(){
let sBreed = "Savannah";
let sType = "Cat";
let text = `Animal: ${sBreed}, ${sType}.`;
return text;
}

Template Literal Expression

A template literal with an expression allows an expression within a template. The template begins with ${ and ends with }.

The expression (start * growth).toFixed(2) evaluates between the brackets ${...}. The result should display Final: 27.50. Click a box to see the result, below. The following function includes the code to return a string from a template literal with an expression.

function fTempExp(){
let start = 22;
let growth = 1.25;

let final = `Final: ${(start * growth).toFixed(2)}`;
return final;
}

Click a Box

Template Literal Substitution

function fTemplate(){
let sBreed = "Savannah";
let sType = "Cat";
let text = `Animal: ${sBreed}, ${sType}.`;
return text;
}

Template Literal Expression

function fTempExp(){
let start = 22;
let growth = 1.25;

let final = `Final: ${(start * growth).toFixed(2)}`;
return final;
}
	

Closures

Declare a closure as a child function within a parent function. The child function retains access to properties in the parent scope.

Simple Factorial

Call factorial() the number of times you want to calculate a factorial, starting at one. The factorial from one to four should equal 1 * 2 * 3 * 4 = 24. The following code displays a simple method to process the factorial of four. The last statement, this.innerHTML = factorial(); is the fourth call to factorial() and displays the result in an HTML element.

factorial(); factorial(); factorial(); this.innerHTML = factorial();
Simple Factorial Closure

Tap a box below to see closure examples in action. The simple factorial closure source code displays below.

/**
 * Factorial equals the
 * product of a series of numbers.
 * 1 * 2 * 3 * 4...
 */
const factorial = (function () 
{
 let f = 1;
 let r = 1;
 
 // The closure:
 return function () 
 { 
  console.log("f: "+f+ ", r:"+r);
  console.log("f * r: " +f * r);
  r = f * r;
  f += 1; 
  return r;
 }
}
)();
Factorial with End Value Parameter

A slightly simpler closure includes a parameter which indicates the factorial end point. For example if you want to see the factorial of seven, call factorialN(7);.

Pass a parameter to the factorial function. The parameter indicates the last number in a series of products. For example if you call factorialN(4), the result should equal 1 * 2 * 3 * 4 = 24.

Tap a box below to see both closure examples in action. The code below demonstrates one technique to use a closure to process factorials. However closures have many more uses.

/**
 * Factorial equals the
 * product of a series of numbers.
 * 1 * 2 * 3 * 4
 * @param n: Number representing 
 * end of factorial calculation.
 */
const factorialN = (function (n) 
{
 let f = 1;
 let r = 1;
 return function (n) 
 { 
  for (var i = 0; i < n; i++){
   console.log("f: "+f+ ", r:"+r);
   console.log("f * r: " +f * r);
   r = f * r;
   f += 1; 
  }
  return r;
 }
}
Tap the Box

Call factorial from one to four. Should equal 24.

Enter Factorial Digit Below:

0

Promises

Promises link long running code with result handler functions, which wait for a response.

Producer
Code that takes time.
Consumer
Code that waits for result.
Promise
Link between Consumer and Producer

Order

First define your promise handler or handlers. Second create a Promise object. Third call the promise.

  1. Define Promise Handler; displayInfo().
  2. Create Promise object; var promiseButton = new Promise(...)
  3. Call Promise; promiseButton.then(...)

Promise Handler

Define a promise handler that simply displays the result. This handler can be used if the Promise results in an error, or acceptable responses.

function displayInfo(sInfo){
let eDebug = document.getElementById('eDebug');
eDebug.innerHTML = sInfo;
}

Create a Promise

The following code creates a Promise with status handlers for either an error or acceptable responses.

This promise handler calls an XMLHttpRequest() to download an XML file.

/**
* New Promise object
* Inline function
* declared in parameter list.
*/
var promiseButton = new Promise(

// Inline function
// in parameter list.
// Two function names passed
// as parameters within
// inline function.
function(resolveOK, resolveError) {

// Open HTTP request:
let req = new XMLHttpRequest();

// Obtain ss-promise-got.html:
req.open('GET', 
"assets/ss-promise-got.html"
);

// Attempt to load
// ss-promise-got.html:
req.onload = function() {

if (req.status == 200) {

// Download went well.
// Call function in
// parameter list.
resolveOK(req.response);

}

else {

// Download error.
// Call second function
// in parameter list.
rejectError("File not Found");

}

};


// Execute the download:
req.send();

});

Call a Promise

Call the promise, with the actual functions replace formal parameters for resolveOK() and resolveError() functions with the actual parameter displayInfo().

Place parameter functions in the order they're declared with promiseButton = new Promise(...). The following function, promiseCall() responds when the user taps a button.

function promiseCall(){
promiseButton.then(
function(value) {displayInfo(value);},
function(error) {displayInfo(error);}
)
}

The following HTML markup executes promiseCall() when the user taps the div element.

<div 
id="eDebug"
onclick="promiseCall()"
>
</div>

Tap for Promise

The button below calls a function which activates promiseButton.then(...). I created the promiseButton, outside of the calling function, with a var instead of let. That allowed me to define the promise earlier, and allows the function to access the promise.

Tap the Button!

Arrow Functions

Arrow functions have a unique signature, and different parent element, than normal JavaScript functions. Signature pseudo code, for an arrow function, follows.

functionName = (parameters) => function body;

You can remove brackets and the return a value to functionName, for functions with only one statement and a return value.

The following two function definitions demonstrate how to accomplish the same task with either a normal function or an arrow function.

Return the value after operator =>.

// Normal function:
fHi = function() {
return "Hi Web Developer!";
}

// Arrow function:
fHi = () => "Hi Web Developer!";

The following two examples demonstrate arrow functions with parameters.

// Normal function:
function fMultiply(a,b){ 
return a * b;
}

// Arrow function:
let fMultiply = (a, b) => a * b;

Normally the this property is the object that calls a function, such as a button. With arrow functions this property is the function's owner, in this case the owner is the window.

// Normal
fNormal = function() {
btnNormalTxt = document.getElementById("btnNormalTxt");
btnNormalTxt.innerHTML = this;
}

document.getElementById("btnNormal").addEventListener(
"click", 
fNormal
); 

// Arrow
fArrow = () => {
btnArrowTxt = document.getElementById("btnArrowTxt");
btnArrowTxt.innerHTML = this;
}

document.getElementById("btnArrow").addEventListener(
"click", 
fArrow
); 

Tap Both Buttons

The small text, toward the bottom of each button, tells you which type of object this represents.

Rest Parameters

Rest parameters allow JavaScript variadic functions. When the function's defined, include a rest parameter, preceded by three dots, such as f(...restParam);. You may treat the rest parameter as an array.

A variadic function includes a variable number of parameters. Developers can modify the number of parameters when the function's called.

Rest parameters are also called spread operators.

Rest Example

For example, the following function, fRest(), displays the first two parameters, p1 and p2, with the last parameter, aryMore. Tap the red box to see the results. Notice the parameter, ...aryMore, displays as an array. See the HTML Simple Rest Markup.

function fRest(p1, p2, ...aryMore) {

let eRest = document.getElementById('idRest');

eRest.innerHTML = "p1: "+p1+"<br>p2:"+p2+"<br>aryMore:"+aryMore+",";

}

Simple Rest Markup

Function fRest() displays the first two parameters, Greyhound, Poodle as unique values. The last three parameters, Boxer, Chihauhau, Shepherd, display as the contents of an array.

<div 
class="box rd"
id="idRest"
onclick="fRest(
'Greyhound',
'Poodle',
'Boxer',
'Chihuahua',
'Shepherd'
)";
>

Tap to call fRest()

</div>

Rest Buttons

Tap to call fRest()

Tap to call fReduce()

Combine Arrow, Rest Parameter, Array Reduce

This section applies the Array reduce() method, with an arrow function on a rest parameter.

Function: Arrow with Reduce Array

The reduce() array method iterates over an array. Method reduce() applies the result of each previous call to the current call of a developer defined function. The end result is one value.

The first parameter to reduce() is a developer defined function. The second, optional, parameter is the starting value for the developer defined function.

The following code defines a function for reduce() that multiplies the sequence of values in an array. Tap the green box to see the results of the fReduce() function, below.

// Arrow function
// Multiplies a series
// of numbers in an array.
const fReduceMultiply = (prev, curr) => prev * curr;

function fReduce(){
// Obtain the button.
let eReduce = document.getElementById('idReduce');

// Declare an array.
let aryOneToFour = [1, 2, 3, 4];

// 1 * 2 * 3 * 4 = 24.
eReduce.innerHTML = aryOneToFour.reduce(fReduceMultiply));
eReduce.innerHTML += "<br >";

// 5 * 1 * 2 * 3 * 4 = 120.
// Call fReduce with an initial value of five.
eReduce.innerHTML += aryOneToFour.reduce(fReduceMultiply, 5));

}

Order With Rest Array

Only one rest parameter is allowed per function and that rest parameter must be the last or only parameter. As you saw earlier, functions accept individual parameters passed before the rest array.

Order with Reduce Method

With array's reduce() method, the first parameter is an array, however the last parameter can provide the initial value to apply for reduce.

Rest Versus Reduce

Functions with Rest parameters require the Rest (array) parameter last and optional other parameters first. The array reduce() method requires the array parameter first and optional initial value last.

After some testing it appears that developers might not be able to pass non Rest parameters to the reduce() method. However perhaps that depends on the current browser's JavaScript version..

Product Arrow Function: Rest Parameter

Now create a function with a rest parameter then apply the reduce function defined previously, named fReduceMultiply().

The following simple function iterates over every value in rest parameter (array), ...aryArgs, multiplying each value by the preceding value. The product is returned.

/**
* Multiply every value in ...aryArgs.
* @param Rest or spread parameter: ...aryArgs
* @returns: product of array values.
*/
function fMult(...aryArgs) {
return aryArgs.reduce(fReduceMultiply);
}

Markup: Rest, Multiply, Arrow

<div 
class="box y"
onclick="this.innerHTML = fMult(1,2,3,4)"
>
Tap to Multiply:<br>
(1,2,3,4)
</div>

Sum Arrow Function: Rest Parameter

Implement a function with a rest parameter. Define and call an arrow function to sum every value in the rest parameter's array. Return the sum.

/**
* Sum every value in ...aryArgs.
* @param Rest or spread parameter: ...aryArgs
* @returns: sum of array values.
*/
function fSum(...aryArgs) {
 return aryArgs.reduce((previous, current) => {
   return previous + current;
 });
}

Markup: Rest, Sum, Arrow

The following markup declares a box. Click on the box to see the sum of the rest parameter, 1,3,4,5. Try It: Rest, Arrow: Sum & Product.

<div 
class="box vi"
onclick="this.innerHTML = fSum(1,2,3,4)"
>
Tap to Sum:<br>
(1,2,3,4)
</div>

Try It: Rest, Arrow: Sum & Product

Tap to Multiply:

(1,2,3,4)

Tap to Sum:

(1,2,3,4)

Strict Mode

Strict mode was enabled in ECMAScript 5. Most browsers now support strict mode, yet older browsers ignore the simple string declaration. Strict mode throws an exception when the developer violates good practices, such as attempting to write to an undeclared variable, undeclared object, undeclared property or getter only property. Strict mode throws exceptions with many other violations of good practice, or use of reserved keywords, in preparation for future JavaScript versions. See the following lists for examples.

Strict Mode Errors

The following list includes examples which will throw an exception in strict mode.

Assign to Non Declared Variable
notStrict = "Throws an Error.";
Assign to Non Declared Object
myObject = {x:256,y:512}
Deleting a Variable
var firstName = "Doris"; delete firstName;
Deleting a function
function f(){ var x = 20;} delete f;
Duplicate Parameters
function f(x,x){var y = 0;}
Octal Literals
Use character o after zero. Use var y = 0o256;, rather than var y = 0256;
Octal Escape Characters
Use hexadecimal escape sequences, \x45, not octal escape sequences, \105.
Write to Read Only Property
var obj = {};
Object.defineProperty(obj, 'name', { value: 'Doris', writable: false });
obj.name = 'Tony';
Write to Get Only Property
var obj ={get v(){return "v";}; obj.v = "a";

Reserved Keywords or Expressions

This list provides a clue as to which features W3C plans to implement in the future. For example perhaps access modifiers private, protected and public are on their way.

Don't use the following words as variables, functions or expressions, in strict mode.

this Property

In strict mode, the keyword this returns either the object that calls a function or undefined. In normal mode, the keyword this returns either the the object that calls a function or the window.

Apply Strict Mode

If you want JavaScript to run in strict mode then place the line, use strict;, at the top of a file. Strict mode then applies to the entire file. It's global.

If you want a function only, to run in strict mode, then place, use strict;, as the first line in a function. The following function throws an exception because variable i is not declared before it's used.

function fStrictModeBad(){
"use strict";
// Throws an exception:
i = 3; 
}

The following function should execute fine.

function fStrictModeOK(){
"use strict";
let i = 3; 
}

Tap to Execute Bad Function:

function fStrictModeBad(){
"use strict";
try{
// Throws an error
i = 3; 
return i;
}
catch(ex){
return ex.toString();
}
}

Tap to Execute OK function:

function fStrictModeOK(){
"use strict";
try{
let i = 3;
return i;
}
catch(ex){
return ex.toString();
}
}

Modules

Modules allow developers to implement shared functionality while also protecting functions, methods and properties.

Simple Module Export

Modules are simply files which enable sharing of functions, methods and properties. However you can't externally modify those functions, methods and properties. Use the keywords export and import to access features declared in one file, from another file.

Module to Export

Create a file for modules. Let's call it export-first-header.js. This file will import from the header, so we want it simple.

Apply the export keyword to function popupMessage() See JavaScript file export-first-header.js.

For example create the following exportable function in export-first-header.js. The function displays a string in the alert dialog.

/**
* Display an alert with a message.
* @param sMessage: String
*/
export function popupMessage(sMessage) {
alert(sMessage);
}

Simple Module Import

Imports allow developers to load read-only modules of JavaScript, for use in their own files. Imports automatically load in strict mode.

Imports require CORS. Optionally copy pages and files to the same Web server.

Module Scope

Scripts loaded as a module are scoped to the script itself. That makes access within or without the script a challenge. Some people suggest adding the module to the window object. That doesn't seem like good practice, but it might work best for your situation.

The following inline script imports everything exported from export-first-header.js to m. The script's imported as a module, within the header of JavaScript: Simple Module Example. As after the file loads, you'll see an alert which displays the text, First Module.

<script 
type="module"
>

import * as m from './javascript/export-first-header.js';

// Use the exported function
// from export-first-heaader.js:

m.popupMessage('First Module');

</script>

Try Import & Export

See JavaScript: Simple Module Example. Later tap the Simple Module button, here to see a simple onclick event listener with modules.

Class: Module, Import, Event Listener

This section demonstrates how to create a class module for import and export. Classes obviously enable many web development possibilities. Here we'll just focus on an onclick event listener. You'll import the module then assign a module method as a click event listener, to a button.

Many online questions revolve around finding a simple solution to assign a straight forward JavaScript import, as an event listener. Here's one relatively simple example. You'll see the other, even simpler, technique with the Simple Module button.

Export Class

The following export module file, export-class.js, declares a class with two static functions. The first static function, fLog(), prints out to the console, for debugging purposes. The second static function, fBtnText(), changes the text on our button.

The last line declares that this class is for exporting, with export { expClass }. The entire JavaScript follows.

class expClass {
	
/**
* Log the function name,
* and parameter value.
	
* @param val: String
*/
static fLog = function(val) {

// The class and function:
console.log('expClass.fLog()');

// Name of parameter:
console.log('log:'); 


// Value of parameter.
console.log(val); 

};


/**
* Change text on
* button when it's tapped.
*
* Note this example expects
* your button to include an 
* element with the ID 'btnText'.
*/
static fBtnText = function() {

// Get the button's main text area:
let btnTxt = document.getElementById('btnTxt');

// Let user know, button clicked:
btnTxt.innerHTML = "Button Tapped!";

// Move to the button text:
window.location="#btnTxt";
};

};

export { expClass }

Module: Import Our Class

Import modules, in the header, with the attribute type assigned the value module. Obtain our button by ID, btnMod. Assign the expClass static method, fBtnText, to the button's onclick event listener.

View or download the JavaScript file, export-class.js. View or download the JavaScript file, import-class.js. Tap the Class Module button, and its text changes. The click event listener, from our module, fBtnText() activates.

Include Module: in Header or External File

you can include your import module within the header, or inline. Optionally you can include your import module as an external file. The following listing demonstrates adding a module to the header, or inline.

<script 
type="module"
>

// Import the class:
import {expClass} from './javascript/export-class.js';

// Call the logging function.
// Look in your console log:
expClass.fLog('Test Logging: Export Class');

// Obtain our button.
btnMod = document.getElementById(
'btnModClass'
);


if(btnMod != null){

// Add the on click listener:
btnMod.addEventListener(
'click',
expClass.fBtnText,
false
);

// Log that we have this button:
console.log(btnMod);

}
</script>

The following listing demonstrates adding import-class.js externally from a JavaScript file.

<script 
async  
type="module"  
src="javascript/import-class.js">
</script>

Tap a Module Button!

The following two buttons respond to module event listeners. the Simple Module button activates function popupMessage(), declared in export-first.js. The Class Module button activates method fBtnText() declared in file export-class.js.

Button Markup

HTML markup for the button displays below.

<button 

class="btn" 
id="btnModSimple"

title="Module Simple">

<span 
class="txt"
>
Simple Module
</span>

</button>


<button 

class="btn" 

id="btnModClass"

title="Class Module">

<span 
class="txt"
id="btnTxt"
>
Class Module
</span>

</button>

Summary

You learned many new or advanced JavaScript techniques including template literals, template literals with expressions, promises, closures, arrow functions, rest parameters, strict mode, modules including simple imports with exports, and class imports with exports. We also combined rest parameters with arrow functions.

See the JavaScript advanced.js source file for everything, except modules, on this page.

Module Code

See simple module Javascript files export-first.js with import-first.js and more complex class modules with export-class.js and import-class.js.

Learn JavaScript

JavaScript's the foundation of Web developer and Website design skills. This free and unique JavaScript tutorial includes some new or seldom used, but useful features.

Tags
canvas drawing, web design, web designing course, how to become a web developer, coding websites, website developers,learning web design, html web design, html5 canvas tutorials, coding Website, html5 canvas, learn to code, html5 canvas tutorial,learn html tutorial, simple html tutorial

Ads >
Create 3D Games: Learn WebGL Book 2 Simple Shaders: Learn WebGL Book 4
3D Programming for Beginners: Learn WebGL Book 1

for Web graphics!

Copyright © 2022 Amy Butler. All Rights Reserved.