Organizing Your JavaScript Code with Functions
Tags: beginners, tutorial, javascript, functional
Published: 2020-01-02 15:40:32

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

**Follow me on Twitter at https://twitter.com/AuMayeung**

**Many more articles at https://medium.com/@hohanga**

Functions are small blocks of code that take in some inputs and may return some output or have side effects, which means that it modifies some variables outside the function. We need functions to organize code into small blocks that are reusable. Without functions, if we want to re-run a piece of code, we have to copy it in different places. Functions are critical to any JavaScript program.

Defining Functions
==================

To define a function, we can do the following:

```javascript
function add(a, b){  
  return a + b;  
}
```

The function above adds 2 numbers together and returns the sum. `a` and `b` are parameters, which lets us pass in arguments into the function to compute and combine them. `add` is the name of the function, which is optional in JavaScript. The `return` statement lets the result of the function be sent to another variable or as an argument of another function. This is not the only way to define a function. Another way is to write it as an arrow function:

```javascript
const add = (a, b) => a + b;
```

The 2 are equivalent. However, if we have to manipulate `this` in the function, then the 2 aren’t the same since the arrow function will not change the value of `this` inside the function, like the function defined with the `function` keyword does. We can assign the function to a variable since functions are objects in JavaScript. Note that the function above only works if it’s one line since returning is implicitly done if the arrow function is one line. If it’s more than one line, then we write it with brackets like so:

```javascript
const add = (a, b) => {  
  return a + b;  
}
```

This way we have to write the `return` statement explicitly. Otherwise, it won’t return a value.

A third way to define a function is to write:

```javascript
const add = new Function('a', 'b', 'return a + b');
```

This allows us to define functions dynamically since all the arguments are strings. However, this is not recommended in most cases since it lets malicious users inject code into your programs if you’re not careful in sanitizing the inputs. Also, it’s a lot harder to read if your function has multiple lines. There almost no need to do this unless you have to define functions dynamically.

Calling a Function
==================

If we are referencing and using a function, then we are **calling** a function.

To call a the function, we write:

```javascript
add(1, 2) // 3
```

Since our function returns a value, if we console log the return value of the `add` function:

```javascript
console.log(add(1, 2)) // logs 3
```

We can also assign the return value to a variable:

```javascript
const sum = add(1, 2);  
console.log(sum) // logs 3
```

Part of a Function
==================

All functions have some or all of the following parts:

*   `function` keyword, which is optional
*   function name, which is optional
*   parentheses — this is required for any function.
*   parameter inside the parentheses, which is optional
*   opening and closing curly brackets — required for all functions except for single line arrow functions
*   `return` statement, which is optional. If a function doesn’t have a `return` statement, it returns `undefined`. A `return` statement which has nothing follow it will end the executing of the function, so it’s handy for controlling the flow of your function.

Using Arguments
===============

As we can see, many functions have arguments. Arguments are data that is passed into a function for computation, so if we have a function call `add(1, 2)`, then 1 and 2 are the arguments. On the other hand, **parameters** are what we write in the parentheses when we define a function to clarify what we can pass in as arguments. We do not have to define a function parameters to pass in arguments since we have the `arguments` object in each function. However, it is not recommended since it’s unclear what you want to pass in. We can use the `arguments` for optional things that we want to pass in, however.

For example, if we go back to the `add` function we defined above:

```javascript
function add(a, b){  
  return a + b;  
}
```

`a` and `b` are parameters. When we call it by writing `add(1, 2)` . 1 and 2 are arguments.

We can specify up to 255 parameters when we define a function. However, we shouldn’t do define more than 5 usually since it becomes hard to read.

Pass in Arguments by Value
==========================

There are 2 ways to pass in arguments in JavaScript. One way is to pass in arguments by value. Passing by value means that the arguments passed in are completely separate from the variables you pass in. The content of the variable is copied into the argument and is completely separate from the original variable if we pass in a variable to a function. The original variable won’t change even if we change the argument variables that we passed in. Primitive data types like string, number, boolean, undefined and the `null` object are passed in by value in JavaScript.

For instance, if we have the following code:

```javascript
const a = 1;  
const addOne = (num) => num + 1  
const b = addOne(a);  
console.log(b);
```

`a` would still be 1 even after we call `addOne` on `a` since we make a copy of `a` and set it to `num` when we are passing in `a` as the argument for the call to `addOne`.

Pass in Arguments by Reference
==============================

Non-primitive are passed into a function by reference, which means that the reference to the object passed in as the argument is passed into the function. The copy of the content is not made for the argument and the passed in object is modified directly.

For example, if we have the following code:

```javascript
let changeObj = (obj) => obj.foo = 'bar'  
const obj = {  
  foo: 'baz'  
}  
changeObj(obj);  
console.log(obj); // logs {foo: "bar"}
```

The original `obj` object is defined as `{ foo: 'baz' }`. However, when we pass `obj` into the `changeObj` function, where the passed in `obj` argument is changed in place. The original `obj` object that we passed in is changed. `obj.foo` becomes `'bar'` instead of `'baz'` as it’s originally defined.

Missing Arguments
=================

You do not need to pass in all the arguments into a function in JavaScript. Whatever argument that’s not passed in will have `undefined` set in its place. So if you don’t pass in all the arguments, then you have to check for `undefined` in the arguments so that you don’t get unexpected results. For example, with the `add` function that we had:

```javascript
function add(a, b){  
  return a + b;  
}
```

If we call `add` without the second argument by writing `add(1)`, then we get `NaN` since 1 + `undefined` is not a number.

Default Function Parameter Values
=================================

We can set default function parameters for optional parameters to avoid unexpected results. With the `add` function, if we want to make `b` optional then we can set a default value to `b`. The best way to do it is:

```javascript
function add(a, b = 1){  
  return a + b;  
}
```

In the code above, we set `b` to 1 so that we if we don’t pass in anything for `b`, we automatically set `b` to 1. So if we run `add(1)` we get 2 instead of `NaN`.

An older, alternative way to do this is to check if the type of the parameter is `undefined` like so:

```javascript
function add(a, b){  
  if (typeof b === 'undefined'){  
    b = 1;  
  }  
  return a + b;  
}
```

This achieves the same purpose as the first function, but the syntax is clumsier.

Calling Functions with More Arguments that Parameters
=====================================================

In JavaScript, we can also call a function with more arguments than parameters. If we just pass them in without getting them from the `argument` object, they’ll be ignored. You can get the extra arguments that aren’t in the parameters with the `argument` object and use them. The argument object has the parameters with numerical keys just like the indexes of an array.

For example, if we call the `add` function with extra parameters:

```javascript
function add(a, b){  
  console.log(arguments);  
  return a + b;  
}  
add(1,2,3)
```

We should get:

```javascript
0: 1  
1: 2  
2: 3
```

in the `console.log` call, in addition to the `length`, which should be logged as 3.

Variable Scope in Functions
===========================

Functions inside shouldn’t be accessible outside of functions unless they are global variables. We should avoid defining global variables as much as we can to avoid bugs and hard to trace errors since they can be accessed anywhere in the program. To prevent defining global variables, we should use `let` to define variables and `const` to define constants. For example, we should define functions like so:

```javascript
function add(a, b){  
  let sum = a + b;  
  return sum;  
}
```

In this case, we have `sum`, which is only accessible within the function since it’s defined with the `let` keyword.

Anonymous Functions
===================

Anonymous are functions with no names. Since they have no name, they cannot be referenced anywhere. They are often passed into other functions as callback functions, which is called when the function is passed into an argument. However, you can assign anonymous functions into a variable so it becomes a named function.

They can also be self-executing. This is means that you can define the function and make it run immediately. For example, if we write:

```javascript
const sum = (function(a, b){  
  return a + b;  
})(1, 2);
console.log(sum) // log 3
```

We log 3 because we defined a function to add 2 numbers, and then passed in 1 and 2 as the arguments immediately after by wrapping the function in parenthesis and then passed the arguments to it.


Recursion
=========

You can call the same function from within itself in JavaScript. This is called recursion. All recursive functions must have an end condition, which is called the base case so that it knows when it stops executing. Otherwise, you can get a function that’s called an infinite number of times, which will crash the browser.

To write a recursive function, we can write:

```javascript
function sumOfSquares(num) {  
  let sum = Math.pow(num, 2);  
  if (num == 1) {  
    return 1  
  } else {  
    return sum + sumOfSquares(num - 1)  
  }  
  return sum  
}
```

In this example, we wrote a function to compute the sum of squares for a given number. We compute the square of `num` and then if we have `num` equal to 1 then we return 1, otherwise we return the sum of `sum` plus the result of call `sumOfSquares` on `num — 1`. We keep reducing `num` so that we can reach the base case of 1, adding up the results while doing so.

Nesting Functions
=================

Functions can be nested within each other. This means that we can define a function inside another function. For example, we can write:

```javascript
function convertToChicken(name){  
  function getChickenName(name){  
    return `Chicken ${name}`;  
  }  
  return getChickenName(name)  
}
```

In this case, we called `getChickeName` inside the `convertToChicken` call. So if we write `convertToChicken('chicken')` , then we get `'Chicken chicken'` since we called get `getChickeName` and returned the result. The scope of variables are the name. `let` and `const` are block-scoped so they cannot be accessed outside of the original function that’s defined, but they are available in the nested function, so if we have:

```javascript
function convertToChicken(name) {  
  let originalName = name; function getChickenName(newName) {  
    console.log(originalName)  
    return \`Chicken ${newName}\`;  
  }  
  return getChickenName(name)  
}
```

Then `originalName` will still be defined in the `console.log`.

Defining Function in an Object
==============================

We can define a function in an object in a few ways. We can use the `function` keyword or arrow function as usual, but we can also write it with a shorthand for the `function` keyword. For example, if we have a `bird` object and we want to define the `chirp` function, we can write:

```javascript
const bird = {  
 chirp: function(){  
   console.log('chirp', this)  
  }  
}
```

or use the following shorthand:

```javascript
const bird = {  
 chirp(){  
   console.log('chirp', this)  
  }  
}
```

The 2 are the same since the `chirp` function will have the `bird` object as the value of `this`.

On the other hand, if you use arrow function:

```javascript
const bird = {  
 chirp: ()=>{  
   console.log('chirp', this)  
  }  
}
```

`this` will be logged as the global `window` object, since arrow functions do not change the value of `this` to the object in which the function is in.

JavaScript functions allow us to organize code into small parts that can be reused. There’re many ways to define a function, but sticking to the commonly recommended ways like using arrow functions and not using `arguments` too much is recommended.