Table of contents
Prerequisite
Good knowledge of HTML and CSS is needed to make the most of functions in JavaScript but it is not required. Although, you need HTML & CSS If you are going for web-based projects and development. Also, general knowledge of what JavaScript is and its benefit to frontend web development is a plus. In that light, newbie and seasoned coders can make good use of this article.
Introduction
A function is a set of statements, mixed with expressions, used to perform specific tasks. Functions make it easier for other developers to understand your code. They are the best way to do repetitive tasks. In JavaScript, all functions are objects. It is safe to say that most data types in JavaScript are objects, including Strings, Boolean, etc. I won’t go into details as it is not in the scope of this article.
So, functions are callable objects. Functions are so powerful; there are the building blocks we use to construct programs. As useful as they are, it can be tricky to make the most use of them. With this article, I hope to simplify most of the things you need to know about JavaScript functions.
Hyped enough? Let’s get started.
Function Declaration
We’d look at how to declare a function in JavaScript;
Functions are declared with an expression that starts with the function keyword. (Although, that’s not always the case as we would later see.)
function gettingStarted (a, b) {
// block of code
statements
}
gettingStarted is the name of the function, written in camelcase.
Personal Opinion: Camel casing is the best practice for writing name conventions in JavaScript.
( ) this bracket takes the function parameters.
// this indicates that everything on this line is a comment The statement is the body of the function.
{ } Curly braces house the whole function.
An example of function gettingStarted doing a specific task:
function gettingStarted ( ) {
console.log(“Hello there!”);
}
// Calls the function
gettingStarted ( )
// Hello there!
Predefined/Built-In Function
There are a set of built-in codes that exist to carry out functions without the need of programmers to create the functions. JavaScript has a ton of predefined functions that help you do tasks easily. Almost all object types in JavaScript have their predefined functions. Ranging from strings, Boolean, arrays, numbers, etc.
Popular built-in String functions include;
chatAt( ), indexOf( ), concat( ), replace( ), match( ), slice( ), toUpperCase( ), toLowerCase( ), and so on.
Example:
toUppercase( ) - Transform to capital letters
let testString = “everyone can code.”;
let result = testString.toUpperCase();
console.log(result);
// EVERYONE CAN CODE.
For Boolean;
valueOf( ), toSource( ), toString( )
Example:
valueOf( ) - Checks for the type of value
let testBool = true;
let resultBool = testBool.valueOf();
console.log(resultBool);
// true
For Arrays;
Map( ), slice( ), filter( ), pop( ), reduce( ), some( ), every( ), includes( ), splice( ), shift( ), unshift( ), fill( ), and so on.
Example:
Includes() - check for a specified value.
let testArray = [ 2, 7, 15, 27, 30, 40 ];
let resultArray = testArray.includes(40);
console.log(resultArray);
// true
For Numbers;
Math.floor( ), cos( ), log( ), random( ), max( ), min( ), sqrt( ), tan( ), round( ), and so on.
Example:
max() - Gets the highest value.
let b = Math.max(40, 150, 80, 300, 800, 400);
console.log(b);
// 800
For Date;
date( ), getMonth( ), getDay( ), getSeconds( ), getFullYear( ), setTime( ), setMinutes( ), toDateString( )
Example:
getFullYear() - gets the current year
let present = new Date();
let presentYear = present.getFullYear();
console.log(presentYear);
// 2022
The upside of Predefined functions
- Speed development process (optimized to run in the least amount of time.)
- Reduced coding time
- Reduced line of code.
- Reusable code
- Readability. (it is common for everyone to understand since it’s the same JavaScript wherever it is used.)
The downside of Predefined functions
- Tasking to change the functionalities of the function
- Minor variations (leads to writing something similar with minor difference)
Named functions
This is a naming convention given to a function. It uses the “function” keyword followed by a named reference used to call the function.Like so;
function newFunction(parameter) {
/ / code block
}
The named function is the most common kind of function, It’s the function you’ll most likely interact with. It consists of the function keyword, the name of the function, the parameters, and the body of the function.
function doAddition (amount, cost ){
return amount + cost;
}
DoAddition (40, 2); // 42
Named function is like having the recipe for spaghetti bolognese, you can always pick it up to use and at any time. You can always call named functions anywhere in your code and at any time.
The upside of a Named function
- Named function is hoisted
- Named function can be called before the declaration
- Readability: Functions can be easily understood based on their names before reading their logic. (That’s if they are correctly named.)
- Easy to debug (since errors in the console will show the function names)
- Reusable code
Recursion is easier with the Named function.
Recursion is a function calling itself to produce an outcome until someone stops it. A simple way to represent recursion is in a number countdown like so;
function countDown (number) { console.log(number); const result = number - 1; If (result > 0) { countDown (result); } } CountDown(5) The console logs: 5 4 3 2 1
With Named function it is easier to identify the players in recursion (base case, function call)
The downside of the Named function
- Tedious when they are not properly named
- Codebase transfer is usually an issue as the naming pattern has to be maintained
Anonymous function
Anonymous functions are function expressions. Usually, functions are declared with the function keyword and then called with the name of the function. This is not the case with an anonymous function. Here, it means calling a function without a name–A function called without any identifier.
You cannot call an anonymous function after declaring because you don’t have access. They can only be accessed when you declare them in a variable as values. A basic anonymous function expression looks like this
let boss = function ( ) {
return (“I am the unknown function”);
}
boss ( );
Here the anonymous function was assigned to a variable “boss” and it's used to print out a string of text.
When “a name is not given to a function during declaration” it is an anonymous (function expression). It can also self-execute (IIFE).
Use Cases of Anonymous function
- Anonymous functions: used as an argument to other functions or as an IIFE.
- Assignment to variables.
The upside of Anonymous function
- Less line of code.
- Flexibility (You can pass them as arguments, combine them with ternary operations and still assign them to properties.) Unlike with named functions where this process leads to verbosity in code.
The downside of the Anonymous function
- The lack of a name identifier.
- It is harder to debug stack traces.
- Self-referencing (recursion, removeEventListener(), etc.) is harder
- Deeply nested anonymous functions are hard to understand.
- They are not hoisted onto the beginning of the scope thus they cannot be used before they appear in the code.
Arrow Function
=> () {}
Introduced with ECMAScript 6 (ES6), as a cleaner way to express functions in JavaScript. They allow us to write functions in shorter syntax. The simple Arrow function expression is written like so;
let arrowFunction = (a,b) => a * b;
Arrow Function Example
let test = (k, b) => {
let answer = k + b;
return answer;
}
test (3,4);
// 7
They are best used with these callback methods map(), forEach(), reduce().
The upside of the Arrow function
- Reduced code lines
- ES6 standards
- Makes code neat
The downside of the Arrow function
- Not (very) beginner-friendly
- Does not work on older browsers except compiled by Babel (and others)
- Cannot be used as constructors
- They are lazily scoped; unsuitable for the call, apply, and bind methods.
- Cannot be used with generator yield.
IIFE (Immediately Invoked Function Expression)
There are functions created and executed immediately after declaration. They are also known as self-executing functions.
IIFE;
- Are not accessible or stored in a variable.
- They cannot be called even if they are named.
- They are recognized by the result/value they leave behind at runtime (execution).
The whole code block of an IIFE must be written in brackets ( ) Let’s see how it works;
(function ( ) {
console.log(“I am an IIFE”);
})
( );
Personal Opinion: Anonymous functions are the best ways to represent and write an IIFE.
They can also be defined with an arrow function like so;
(() => {
/ / Code block
})()
An IIFE can also be a named function, let’s take a look at this example that prints a string to the console.
(function printString() {
console.log(“I can have a name, Isn’t it cool!”
})()
The upside of the IIFE function
- Isolate variable declarations.
- Prevents global variable pollution. (they are usually declared and used in the local scope)
- Seamless code execution
The downside of the IIFE function
- IIFE is not reusable
- Doesn’t help in debugging
Constructor function
The constructor function is a template for creating multiple object instances. It is a kind of function used to create a “new” object. It creates new sets of values (object) for any available object property.
This is a kind of function that initializes an object instance of a class. When you call a constructor function;
- It creates an instance of another object
- this then refers to the current object instance
- new then creates the new objects and sets this object instance to the property of the constructor function
Let’s take a look at an example
// Constructor function named Boss
function Boss( ){
this.job = “Programmer”;
this.age = 23;
this.place= “Spain”;
}
// create objects from the constructor function Boss ( )
const SecondBoss = new Boss( );
const ThirdBoss = new Boss( );
// SecondBoss and ThirdBoss now have all the properties of Boss ( )
// Let’s access the properties
console.log(SecondBoss.place);
// Spain
A Use case of a constructor function
- used to create multiple and unique objects
Arrow functions cannot be used to define constructor functions.
The upside of a Constructor function
- Reusable object instances
Each “new” object instance created is unique to itself. You can add, remove or change its properties and those properties will only be available to that new object instance.
function Boss ( ) { this.job = “Programmer”; } let SecondBoss = new Boss ( ); SecondBoss.habit = “Reading”; Boss.habit; / / reference error SecondBoss.habit; / / Reading
Note: If an object is created with Object Literals new properties can change the original values of the object. However, this is beyond the scope of this article.
Generator function
This is a function that can stop midway into execution and resume later from where it stopped. It produces a series of results as opposed to normal functions that produce a single result. Generators help us create better iterators with functions. They return values that you can call the next method on.
Generator Function is created like a function with slight addition added to the syntax * (asterisk).
How it works
- The generator returns an object which becomes an iterator,
- yield is used to pause the function,
then the next ( ) method is used to resume/control the returned iterator.
The generator function came with the “yield” keyword that makes it possible to
pause itself
- send a value back
- Retain its state, so the function can continue execution from where it left off.
The generator function syntax is not so far from the normal function. Here’s the syntax for the generator function
1. function * showGenerator() { // block of code}
2. function* showGenerator( ) { //block of code}
3. function *showGenerator( ) { //block of code}
Either of these syntax works. It does not matter how you write it, but an asterisk comes before the name of the function.
As you noticed, it is a normal function with slight addition on the declaration. The (asterisk *) sign is stating that this is a special class function - generators.
Use cases of the Generator function
- Used to write function iterators.
- Better async functionality
- Infinite data stream
The upside of Generator functions
- Helps to write better async functions
The downside of Generator functions
- There cannot be used with the new keyword to create new objects
- They cannot be used/converted to arrow functions.
- You can’t yield inside a callback in generators
- Not memory efficient
- Lazy Evaluation
Function scope
When you define a function it creates a scope. Every variable declared in a JavaScript function is a local variable to that function and accessible within that function. The code block in a function has access to;
- the function’s arguments.
- local variables declared inside the function.
- variables declared in its parent function’s scope.
- global variables.
Scope Chain: When JavaScript tries to get a variable it first looks for it in the local(current) scope, if it does not find it, it goes a scope higher. This operation goes on till the variable is found, if it does not find it in the global scope it returns a reference error.
The JavaScript function scope defines the scope for variables declared with var, let, and const. These variables are not accessible outside of the functions they are declared in but there is an exception to “var”.
With functions scope, let and const usually fall into block scope. Block scope: Variables declared within curly braces.
const Fun = 300;
let Fun = 320;
console. log(`I have ${Fun} bucks`);
// Uncaught SyntaxError: Identifier 'Fun' has already been declared
// This also fails
const Fun = 300;
Fun = 320;
console. log(`I have ${Fun} bucks`);
// Uncaught TypeError: Assignment to constant variable at <anonymous>
Regardless of how you try to redefine it, you cannot redeclare a variable that has already been scoped to a const. let is also block-scoped but its difference from const is it allows reassignment to variables. Example:
let meal = "Rice";
meal = "Spaghetti";
console. log(`I make the best ${meal}`)
// I make the best Spaghetti
Function in strict and non-strict mode
Strict mode makes it easier and possible to write “secure” code in JavaScript. They can be declared globally or just before a function declaration (Local strict mode). With strict mode in functions;
- You cannot use a variable without declaring it
- There can be no duplication of parameters names
(For example, in strict mode, function parameter names cannot be duplicated)
'use strict'
function foo(a,b,a) { }
function bar(a,b,a) {
return foo;
}
console.log(foo);
Log output: Uncaught SyntaxError: Duplicate parameter name not allowed in this context.
Without strict mode, the code block parses just fine!
Function Tips
- Always use descriptive function names
- Be consistent in your naming conventions. There should be a flow down your code.
- It is best to have long function names with shorter ones without any real meaning or flow.
- Functions (codes) are better with comments!
- Split function to specific tasks to avoid tearful debugging.
- Avoid excessive function nesting
- Avoid excessive function arguments
- Study other people’s function
Conclusion
Functions are an interesting and vital part of programming, we all call them “The building block” so it is best to understand how to work and to best make proper use of them. JavaScript functions are easy to work with and are better when they are specific to a task.
Thank you for reading. Happy coding!
References
Understanding Arrow Functions in JavaScript | DigitalOcean
IIFE - MDN Web Docs Glossary: Definitions of Web-related terms
Understanding Generators in ES6 JavaScript with Examples
All about Functions and Scopes in JavaScript - GeeksforGeeks