HomeSearch

JavaScript function Examples

Design functions with arguments and return values. Use immediately-invoked functions.

Function.

A bridge crosses the peaceful lake. The scene is beautiful. A gentle breeze causes a ripple in the water. A bridge is a structure that has a function.

A function

in JavaScript can be anonymous. We can invoke a function immediately. We declare a function with the function keyword or the => symbol.

First example.

JavaScript programs are full of functions. When we see console.log, this too is a function call—one we do not need to define ourselves.

Here: We introduce multiplyBy2, a function that receives an argument and returns that value multiplied by 2.

JavaScript program that uses simple function function multiplyBy2(value) { "use strict"; // Multiply the argument by 2. return value * 2; } // Call the function. console.log("FUNCTION RESULT: " + multiplyBy2(4)); Output FUNCTION RESULT: 8

Function argument.

We can create an anonymous function, and pass it as an argument to another function. Here we invoke forEach, which loops over the elements of an array.

And: A function that prints the element to the console is called on each iteration.

JavaScript program that uses function object as argument // Print 3 integer elements with an anonymous function. // ... Pass the function as an argument to forEach. [10, 20, 30].forEach(function(x) { "use strict"; console.log("VALUE IS: " + x); }); Output VALUE IS: 10 VALUE IS: 20 VALUE IS: 30

IIFE example.

Sometimes a function must be called once, and right where it is defined. An IIFE an immediately-invoked function expression. It helps us manage scope.

Tip: We have code that is as easy to write as top-level code, but it is in a function. The "animal" variable goes out of scope.

JavaScript program that uses IIFE (function() { var animal = "cat"; document.getElementById("animals").textContent = animal; })();

Return.

A function can return a value. Often we use if-statements to branch inside a function, and then return the correct value. A return is not required for all functions.
JavaScript program that uses return keyword function getWord(n) { // Return string representation of number. if (n === 1) { return "one"; } else if (n === 2) { return "two"; } else { return "unknown"; } } console.log("GETWORD: " + getWord(1)); console.log("GETWORD: " + getWord(2)); console.log("GETWORD: " + getWord(1000)); Output GETWORD: one GETWORD: two GETWORD: unknown

Return, void function.

Suppose we try to use the return value of a function, but no return value is reached. We get the special value "undefined."
JavaScript program that uses return function getWord(n) { if (n === 1) { return "one"; } } // If no return statement is reached, we get undefined. console.log("RESULT: " + getWord(1000)); Output RESULT: undefined

Arrow function.

Early versions of JavaScript do not have arrow functions. But browser support for arrow functions has emerged. We have a left and a right side separated by a => operator.

Left: The left side of the arrow function is a list of arguments—this is the same as a "function" in JavaScript.

Right: This is the return value of the function. The value is computed and returned (no "return" keyword is used).

JavaScript program that uses arrow function, var // Use an arrow function and store the function in a variable. var pets = (cats, dogs) => (cats + dogs) // Call arrow function. var result = "I have " + pets(1, 2) + " pets."; console.log("ARROW FUNCTION: " + result); Output ARROW FUNCTION: I have 3 pets.

Benchmark, IIFE.

Usually an IIFE is best used to isolate a nontrivial piece of code. When we use an IIFE in a hot loop, our code will slow down.

So: Use immediately-invoked function expressions to establish scope and help the garbage collector, not in hot loops.

Result: The two versions of IIFE syntax, with parentheses in slightly different places, incur a cost.

Note: I did not find a consistent improvement in one or the other. So the two IIFE syntax forms are likely equal in performance.

JavaScript program that benchmarks IIFE syntax, version 1 var x1 = performance.now(); var test = 0; for (var i = 0; i < 100000; i++) { test += (function() { return 1; })(); } var x2 = performance.now(); document.title = (x2 - x1) + "/" + test; JavaScript program that benchmarks IIFE syntax, version 2 var x1 = performance.now(); var test = 0; for (var i = 0; i < 100000; i++) { test += (function() { return 1; }()); } var x2 = performance.now(); document.title = (x2 - x1) + "/" + test; JavaScript program that in lines IIFE var x1 = performance.now(); var test = 0; for (var i = 0; i < 100000; i++) { test += 1; } var x2 = performance.now(); document.title = (x2 - x1) + "/" + test; Output 14.92 ms IIFE 15.22 ms IIFE 4.93 ms += 1

IIFE, notes.

In my testing, placing a block of code in an IIFE can improve performance by making globals into locals. But a small cost is incurred to call the surrounding function.

Tip: I suggest using IIFE around "units" of code to establish scope and allow the GC to clean up a page.

Optimization, polymorphic arguments.

A function can receive an argument of any type. But if we call a function with varying (polymorphic) argument types, this can thwart optimization.

So: We can improve performance by always calling a function with the same type of argument.

Version 1: The first program calls test() with a string and a number argument. The function can receive either strings or numbers.

Version 2: The second program always calls test() with a string argument. It does not handle numbers directly.

Result: We have better performance when calling a function with non-polymorphic arguments (we always use strings here).

JavaScript program that has function that handles 2 types function test(value) { // Handle string or number argument. if (typeof value === "string") { return (value.charCodeAt(0) - 48) * 2; } else if (typeof value === "number") { return value * 2; } } var x1 = performance.now(); for (var outer = 0; outer < 100000000; outer++) { // Call method with string or number argument. if (test("1") != 2 || test(2) != 4) { break; } } var x2 = performance.now(); document.title = x2 - x1; JavaScript program that has function that handles 1 type function test(value) { // Handle only string argument type. return (value.charCodeAt(0) - 48) * 2; } var x1 = performance.now(); for (var outer = 0; outer < 100000000; outer++) { // Always uses string argument. if (test("1") != 2 || test("2") != 4) { break; } } var x2 = performance.now(); document.title = x2 - x1; Output 192.86 ms test("1") || test(2) 185.67 ms test("1") || test("2")

Optimization, function reduction.

JavaScript functions are objects—this means they are often allocated and garbage-collected. Invoking the garbage collector tends to be slow in languages.

So: One optimization for JavaScript is to reduce the count of functions—combine them or eliminate them unless needed.

Benchmark: In V8 I found that combining functions tends to increase page load performance—the GC is run less and less allocation is done.

Note: To reproduce this, try timing a complex page with many functions. Then combine them and then time the new version.

JavaScript program that uses separate functions function single1() { document.write("A; "); } function single2() { document.write("B"); } // Call single functions. single1(); single2(); Output A; B JavaScript program that uses combination function function combo(x) { if (x === 0) { document.write("A; "); } else { document.write("B"); } } // Call combination function. // ... This saves 1 allocation over 2 separate functions. // ... But benchmark to ensure better performance. combo(0); combo(1); Output A; B

Multiple return values.

A JavaScript program can return multiple values from a function. An array or object (passed by a reference, or created in the function) can be used.Multiple Return Values

Lookup table.

We can develop a lookup table of functions. Then we can skip if-statements, and access functions based on a value. This requires some planning.function Lookup

V8 compiler.

Modern JavaScript engines compile code based on function units. Each function is compiled to a bytecode or machine code then executed.

Quote: With Ignition, V8 compiles JavaScript functions to a concise bytecode, which is between 50% to 25% the size of the equivalent baseline machine code. This bytecode is then executed by a high-performance interpreter....

V8 JavaScript Engine: v8.dev

With functions

and IIFE we add structural designs to our JavaScript programs. With immediately-invoked function expressions we gain a simple and powerful way to create scope.
Home
Dot Net Perls
© 2007-2019 Sam Allen. All rights reserved. Written by Sam Allen, info@dotnetperls.com.