Functions

What is a function?

“A function is a JavaScript procedure—a set of statements that performs a task or calculates a value.” - MDN Web Docs

Analogy

Think about some appliances in your kitchen: a dishwasher, refrigerator, toaster, oven, etc. Each of these appliances do a very specific thing – dishwashers wash dishes, toasters toast bread.

And the beauty of them is that they've already been taught how to do those things. (Whenever I want to make toast, I don't need to build a fire from scratch or send lots of electricity through a coil that heats up, then time exactly how long and how close it should be held to the heat.)

Instead, I just put the bread in and then run the toaster. Or I put dishes in the dishwasher and simply turn it on. The appliances were taught once how to do their task, and from then on we can simply run them and expect they will do their assigned tasks.

This is like a function. Oftentimes there will be multiple lines of code I want to run multiple times in my program. Instead of having to type them each out every single time, I can encapsulate those lines into a function and run (or call) that function whenever I want those lines to run.

When the toaster is turned on, the toaster heats up and toasts the bread placed within. Likewise, when a function is called, the function carries out a set of statements.


Defining a function

Use the built-in function keyword followed by the function's name, a set of parentheses (), and a set of curly braces {}, as seen below.

function nameOfFunction() {
    // Code you want to run by calling the function goes here
    console.log("I'm inside a function!");
}

This is an example of a function declaration. There is another way to define functions called a function expression, which we'll hit on later.

Calling a function:

Functions are called by writing the name of the function followed by parentheses ().

nameOfFunction()
// Console Output: "I'm inside a function!"

Nothing will print to the console until nameOfFunction is called. Defining a function does not run it.

Function Parameters

We intuitively think of a toaster that can toast anything we put in (bread, waffles, bagels, etc). It would be nonsensical to own a toaster for every different thing you may want to toast. (Separate toasters for bagels and bread? Ridiculous!)

Our functions aren't smart enough to know that we want to give it unless we tell it to. Enter parameters!

In our analogy:

  • Toasters have openings wherein bread may be placed. These openings will represent a function’s parameters.

Parameters of a function are placeholders for real values that will be given upon calling the function.

function myToaster(toasterSlot1, toasterSlot2) {
    console.log("Toasted:" + toasterSlot1 + toasterSlot2)
}

I naturally wouldn't want to create a new function for every possible bread-waffle-bagel combination. Instead, I allow the function to receive 2 parameters, (toasterSlot1 and toasterSlot2) and output the a string of what is to be toasted. This way, my function is reusable in an infinitely greater capacity just like allowing a toaster to toast whatever fits into its slots. (In this analogy, a toaster usually has other parameters too, such as the darkness level, the "bagel" button, etc.

Arguments

The bread, bagels, and waffles we put into the toaster slots can represent, what is called, arguments for a function.

In functions, arguments are those values we pass into functions according to their respective parameter.

In this example, we will look at a function that adds numbers.

// paramOne and paramTwo are "parameters"
function addNumbers(paramOne, paramTwo) {
    console.log(paramOne + paramTwo)
}

// 1 and 2 are "arguments" passed to the function
addNumbers(1, 2)

// Output: 3

Now what happens if we decide to subtract numbers, and compare the position of each argument.


// numOne and numTwo are parameters
function subtractNums(numOne, numTwo) {
    console.log(numOne - numTwo)
}

// numOne is receiving 5 as its argument
// numTwo is receiving 10 as its argument
addNumbers(5, 10)

// Output: -5;

If 5 and 10 were switched in the arguments, the output changes.

function addNumbers(numOne, numTwo) {
    console.log(numOne - numTwo)
}

addNumbers(10, 5)

// Output: 5

Return Statement

What would happen if our toasters never popped up? We would not only have some very burnt toast, but we also wouldn't be able to get it back. return is the command, which delivers information from the function. Once return is read, the function is terminated and the following statement specifies the information being returned.

function myToaster(slotOne,slotTwo) {
    return 'Toasted: ' + slotOne + ' & ' + slotTwo
}

//values returned from functions may be saved in variables

console.log(myToaster('bagel', 'waffle'))

//Output: 'Toasted: bagel & waffle'

Now observe statements written after a return

function myToaster(slotOne,slotTwo) {
    return 'Toasted: ' + slotOne + ' & ' + slotTwo
    console.log('Catch fire!')
}

console.log(myToaster('bagel', 'waffle'))

//Output: 'Toasted: bagel & waffle'
//Note: The string 'Catch fire!' was not returned

Scope

“the extent of the area or subject matter that something deals with or to which it is relevant."

Now let's take a step back and view functions from a bigger picture.

In JavaScript, we define scope relative to functions, which is known as function scope.

The scope of functions and variables are defined by wherein they are written. The borders, of which, are defined by {}.

Analogy

Imagine walking into Walmart, to go grocery shopping. We picked up most things on our checklist, but couldn't find a good paddle board, a limitation to shopping at our local Walmart.

We then pull out our phones, and go to SUP-lovers.com and buy the latest and greatest paddle board and paddle, one of the greatest perks of the global internet store.

In the following code, we find two global functions, the internetShopping() function and the walmartStore() function. Within the walmartStore() function, we have a walmartshopping() function, which is a local function to the walmartStore(). Note where the functions can and cannot be called.

function internetShopping(){
    // Globally scoped function  
    return 'Bought on the global store';
}

function walmartStore(){
    function walmartShopping(){
        // Locally scoped function
        return 'Bought locally'
    }
    // Calling my globally scoped function
    internetShopping()
    // Calling my locally scoped function
    walmartShopping()

console.log(walMartStore());

//Output: 
    'Bought on the global store'
    'Bought locally'

//Note: we cannot call walmartShopping() outside of the walmartStore()
General Advice

There are many ways we can write code, nonetheless, there are good, better, and best practices.

Consider how potential employers may judge our code, what questions would they ask themselves?

  • “Is this code easy to read?”
  • “Does this function’s name make sense?”
  • “Will team members want to deal with this code?”

Consider how you will explain your code when you run into bugs that need fixing. It’s much easier to explain the error when written simply and neatly.

An easy way to write cleaner code is to simplify and compartmentalize one's code.

function getReady() {
    shower()
    eatBreakfast()
    travelToWork()
}