logo
logo

Functions Cheatsheet

Functions are an essential building block in JavaScript and are used to perform a specific task or calculate a value. Functions are reusable pieces of code that can be called from anywhere in your program, as long as they are defined in the correct scope. To declare a function, you use the function keyword, followed by the function name and the block of code to be executed. Let's take a look at a simple function that logs a message to the console:

function sayHi() {
  console.log("Hi");
}

To call or invoke the function, we simply use its name, followed by parentheses:

sayHi();

This will execute the code within the function, which in this case, logs "Hi" to the console. We can also declare functions with parameters, which are placeholders for values that will be passed in when the function is called. For example, we can modify our previous function to take in a name parameter:

function sayHiTo(name) {
  console.log("Hi " + name);
}

To call this function, we would pass in a name value:

sayHiTo("John");

This would log "Hi John" to the console. Functions can also have access to variables within their scope, which means they can use and modify them. However, it's important to understand scoping in functions, as variables declared within a function are only accessible within that function's scope.

ES6 introduces some new features for functions, such as arrow functions and the spread operator. Arrow functions are a shorthand way of declaring functions and have a concise syntax. For example:

const sayHi = () => {
  console.log("Hi");
}

The spread operator allows us to pass in an array as individual arguments to a function. For example:

function addNumbers(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];

addNumbers(...numbers);

This would return 6, which is the sum of the numbers array.

Default values in ES6 functions

Default values in ES6 functions are a way of defining a default value for a function parameter in case no value is passed in. This saves us from having to check if a value is undefined and assign a default value to it. Here's an example:

function multiplyNumbers(x = 2, y = 5) {
  return x * y;
}

multiplyNumbers(); // output: 10
multiplyNumbers(3); // output: 15
multiplyNumbers(3, 4); // output: 12
In the above example, if we don't pass in any values for
x
and
y
, their default values are used. If we pass in only
x
, the default value for
y
is used. If we pass in both
x
and
y
, those values are used.

Rest parameters

Rest parameters allow us to pass an arbitrary number of arguments to a function. The
...
syntax is used to define a rest parameter. Here's an example:
function logAllArguments(...args) {
  console.log(args);
}

logAllArguments(1, 2, 3); // output: [1, 2, 3]
logAllArguments(4, 5, 6, 7); // output: [4, 5, 6, 7]
In the above example, the
args
parameter is defined with the rest syntax. This means that any number of arguments can be passed to the function and they will be collected into an array.

Using rest parameters to sort and multiply numbers

Rest parameters can be used to perform various operations on an array of numbers. Here are a few examples:

function sortNumbers(...nums) {
  return nums.sort((a, b) => a - b);
}

console.log(sortNumbers(5, 3, 8, 1, 2)); // output: [1, 2, 3, 5, 8]
In the above example, the
sortNumbers
function takes in an arbitrary number of numbers using the rest syntax. These numbers are sorted in ascending order using the
sort()
method.
function multiplyNumbers(multiplier, ...nums) {
  return nums.map(num => num * multiplier);
}

console.log(multiplyNumbers(3, 1, 2, 3, 4)); // output: [3, 6, 9, 12]
In the above example, the
multiplyNumbers
function takes in a
multiplier
value and an arbitrary number of numbers using the rest syntax. The
map()
method is used to multiply each number in the array by the
multiplier
value.

Using rest parameters with the spread syntax

Rest parameters can also be used with the spread syntax to combine multiple arrays or objects into one. Here are a few examples:

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2];
console.log(combinedArray); // Output: [1, 2, 3, 4, 5, 6]
In the example above, we create two arrays
arr1
and
arr2
and then use the spread syntax with the rest parameter
...
to combine them into a single array
combinedArray
.

Example 2: Combining objects

const obj1 = { name: "John", age: 30 };
const obj2 = { gender: "Male", city: "New York" };
const combinedObject = { ...obj1, ...obj2 };
console.log(combinedObject); // Output: { name: 'John', age: 30, gender: 'Male', city: 'New York' }
In this example, we create two objects
obj1
and
obj2
and use the spread syntax with the rest parameter
...
to combine them into a single object
combinedObject
.

Example 3: Using rest parameters with other parameters

Rest parameters can also be used in conjunction with other parameters in a function. Here's an example:

function sum(...numbers) {
  return numbers.reduce((acc, curr) => acc + curr);
}

console.log(sum(1, 2, 3)); // Output: 6
console.log(sum(1, 2, 3, 4, 5)); // Output: 15
In this example, we define a function
sum
that takes in any number of arguments using the rest parameter
...numbers
. We then use the
reduce
method to add up all the numbers and return the sum.

Function expressions

Before we dive into arrow functions, let's review function expressions. A function expression is a way to define a function as a variable. Here's an example:

const sayHi = function() {
  console.log('Hi!');
}

sayHi();
In this example, we've defined a function called
sayHi
using the
function
keyword, and then assigned it to a variable called
sayHi
. We can then invoke the function by calling
sayHi()
.

What are arrow functions?

ES6 introduced a new way to write function expressions: arrow functions. Arrow functions are a more concise way to write function expressions. Here's an example of the same function we defined earlier, but using an arrow function:

const sayHi = () => {
  console.log('Hi!');
}

sayHi();
As you can see, the syntax for defining an arrow function is different from the
function
keyword. Instead, we use an arrow (
=>
) to indicate that we're defining a function.

How to write arrow functions

Arrow functions can take different forms depending on the number of arguments and the complexity of the function body. Here are some examples:

Arrow function with multiple arguments

const multiply = (num1, num2) => {
  return num1 * num2;
}

Arrow function with a concise body

If the function body is a single expression, you can write it more concisely like this:

const double = num => num * 2;

This is equivalent to:

const double = num => {
  return num * 2;
}

Benefits of using arrow functions

Here are some benefits of using arrow functions:

  • Concise syntax: Arrow functions are shorter and easier to read than function expressions.

  • Implicit returns: If the function body is a single expression, you can skip the
    return 
    keyword and the curly braces.
  • Lexical
    this
    : Arrow functions bind the
    this
    value to the enclosing scope, which can make it easier to write code that works as expected.

Arrow functions and built-in array methods

Arrow functions are often used in combination with built-in array methods like
map
,
filter
, and
reduce
. Here's an example of using an arrow function with
map
:
const users = [
  { name: 'Chris', age: 60 },
  { name: 'Jane', age: 30 },
  { name: 'Billy', age: 45 },
];

const getUsernameList = users.map(user => user.name);

console.log(getUsernameList);
In this example, we're using the
map
method to create a new array that contains only the names of the users. We're passing an arrow function to
map
that takes a single argument
user
and returns
user.name
. The arrow function is more concise and easier to read than a traditional function expression.

Default Values

JavaScript allows you to set default values for function parameters. If the function is called without passing a value for the parameter, the default value will be used instead.

function greet(name = 'World') {
  console.log(`Hello, ${name}!`);
}

greet(); // Output: Hello, World!
greet('John'); // Output: Hello, John!
In this example, the
greet
function has a parameter called
name
with a default value of
'World'
. If the function is called without passing a value for the
name
parameter, the default value of
'World'
will be used. If a value is passed, that value will be used instead.

Rest Parameters

Rest parameters allow you to pass an arbitrary number of arguments to a function. This is useful when you don't know how many arguments will be passed to the function ahead of time. The rest parameter is indicated by three dots (
...
) before the parameter name.
function sum(...numbers) {
  let total = 0;
  for (let number of numbers) {
    total += number;
  }
  console.log(`Total: ${total}`);
}

sum(1, 2, 3); // Output: Total: 6
sum(4, 5, 6, 7, 8); // Output: Total: 30
In this example, the
sum
function takes any number of arguments and calculates their total. The rest parameter
numbers
is used to collect all of the arguments into an array. Then, a
for...of
loop is used to add up all of the numbers and calculate the total.

Indeterminate Number of Arguments using the
arguments
Object

JavaScript functions can receive an indeterminate number of arguments by using the
arguments
object. For example, a function can be declared with only two expected arguments but can receive three, as shown below:
function exampleFunction(x, y) {
    console.log(arguments[2]); // Outputs the third argument passed in
}
exampleFunction(1, 2, 3); // Prints 3
In this example, the
arguments
object can be used to access all arguments passed to the function, even if they are not explicitly defined as parameters.
However, it can be clunky to manipulate the
arguments
object as it behaves like an object, not an array. It cannot be sorted or manipulated using array methods. Therefore, the
arguments
object can be converted to an array using the
slice()
method, as shown below:
function exampleFunction(x, y) {
    const args = Array.prototype.slice.call(arguments);
    console.log(args); // Outputs an array [1, 2, 3]
}
exampleFunction(1, 2, 3);
This converts the
arguments
object to an array, allowing us to manipulate it using array methods.

Indeterminate Number of Arguments using Rest Parameters

ES6 introduced a simpler way to pass an indeterminate number of arguments using rest parameters. It is defined using three dots before a parameter name in the function declaration, as shown below:

function exampleFunction(x, y, ...rest) {
    console.log(rest); // Outputs an array [3, 4, 5]
}
exampleFunction(1, 2, 3, 4, 5);
In this example, the
rest
parameter collects any additional arguments passed to the function, allowing us to access them as an array directly.

this
Keyword in Fat Arrow Functions and Traditional Functions

In JavaScript, the
this
keyword is a special keyword that refers to the context in which the function is called. In a fat arrow function, the
this
keyword is inherited from the parent scope and is not redefined, as shown below:
const exampleObject = {
    name: 'Example',
    sayName: () => {
        console.log(this.name); // Prints undefined
    }
};
In this example, the
this
keyword refers to the global object because it is not redefined in the
sayName
method.
However, in a traditional function, the
this
keyword is determined by how the function is called. It can be explicitly bound using the
bind()
method, as shown below:
const exampleObject = {
    name: 'Example',
    sayName: function() {
        console.log(this.name);
    }
};

const boundFunction = exampleObject.sayName.bind(exampleObject);
boundFunction(); // Prints Example
In this example, the
sayName
method is bound to the
exampleObject
using the
bind()
method, and the
this
keyword refers to the
exampleObject
.

Behavior of `this` in Different Contexts

The behavior of the
this
keyword can change based on how the function is invoked, which can lead to unexpected results. Let's look at some common scenarios:
  • Global context: If a function is called without a context, the this keyword will refer to the global object (e.g., window in a web browser, global in Node.js).

  • Object method context: When a function is called as a method of an object, the this keyword refers to the object itself.

  • Constructor context: When a function is used as a constructor to create a new object, the this keyword refers to the new object being created.

  • Event context: In an event handler, the this keyword typically refers to the element that triggered the event.

  • Function context: If a function is called with the apply() or call() method, the this keyword is explicitly set to the first argument passed to those methods.