The anatomy of a JavaScript function, part 1
A gentle introduction to JavaScript functions for beginners
By: Ajdin Imsirovic 03 December 2018
This article is an excerpt from my new book, published on LeanPub, with the following title: The Best Way to Learn JavaScript.
The book is still being written, so I’m running a $5 USD sale for the first 100 buyers.
Once the first 100 copies are sold, I’m raising the price to $10 USD.
When the book is completed in early March 2020, it will be sold for $29,99 USD.
Don’t miss out on the opportunity, get it now from here.
So, If you like the article, buy the book! Save yourself at least 1000 hours of suffering through basic concepts.
JavaScript Functions as Simple Machines
Why a machine, you might ask?
Because machines — conceptually — share many things with JavaScript functions. Although this is a metaphorical resemblance, I think the metaphor is useful.
So let’s start with a definition, sort of.
What is a machine?
Consider this image of a simplified bottle capping machine:
Let’s describe the machine:
- A bottle capping machine puts caps on bottles.
- A bottle capping machine has two ‘inputs’: bottles, and caps
- The machine’s output is a combination of its inputs: A bottle with a cap on top of it.
- The machine has some sort of instructions and performs some work according to those instructions (take a bottle, put it on the assembly line, take a cap, put the cap on the bottle, move the bottle, start from beginning — ‘Yay, it’s a loop!’)
Now we can take the above description of the machine, and put it in a diagram:
How would we describe the above machine, with the help of this diagram, using JavaScript?
Actually, it’s very easy: We’ll just use the labels from the diagram to convert the process into code, as follows:
As we can see above, it was really straightforward to map the labels from the diagram to JavaScript code.
Now, let’s assume you’ve never seen JavaScript code, and describe the code, word by word:
-
function: this is a reserved JavaScript keyword. Reserved keywords are those words that JavaScript reserves for its own use. Examples of such words are var, if, else, function, return, this, true, false, let, const… There are 63 reserved keywords in JavaScript. So, we translate the word “machine” from the initial diagram to the word “function” in the JavaScript language.
-
bottleCapper: this is the name of our “machine”, the name of our function. A function is named using camelCase. A function name can begin with letters, underscores, and dollar signs. A function name can contain letters, underscores, dollar signs, AND numbers.
- parentheses, or “round brackets”, are used in several ways in JavaScript. The one that we care about in the context of this article is: to hold the “raw materials” that our “machine” takes. In other words, parentheses hold the inputs that our function expects. A function can take zero or more parameters. If you’re defining it, it’s up to you. There are also some predefined functions in JavaScript, so sometimes, you cannot choose the number of parameters.
- curly brackets, also known as “braces”, hold the list of “instructions” for our “machine”. They basically tell our function what to output. We can choose what our function outputs using the return keyword. The curly brackets and the code inside are referred to as a block of code. A block of code usually spans several lines. Note: a function will always return something (if we use the return keyword, it will return whatever value we tell it to; if we omit the return keyword, the function will return the value of undefined).
Defining a Function versus Calling a Function
There are two concepts related to functions in JavaScript that we need to understand completely before even starting to code. They are function declarations and function execution.
Declaring a Function in JavaScript
Just like a real machine, a JS function usually gets built once, but it gets run many, many times. When we build a function, we say that we have coded a function definition, or a function declaration, or a function signature. There are different ways that people refer to this, but practically, it’s the same thing.
Executing a Function in JavaScript
This is sometimes referred to as calling a function, or running a function.
How are these two concepts different?
It’s simple:
- to declare a function means “to build a machine”
- to run a function means “to run the machine”
Declaring a function means setting it up, defining the inputs (the “raw materials”) it will use, and specifying the steps the machine needs to take to produce the output. We also specify whether or not we want to explicitly return a custom output, or just the value of undefined.
Running a function is as if we pressed the “ON” button on our machine and got it working.
Here is a diagram of the difference between the two concepts:
Now we are ready to simulate our simplified bottle capping machine in JavaScript.
We will order our computer, using JavaScript, to do the following:
- Build a machine and call it “bottleCapper”
- The machine should take 2 inputs (a bottle and a cap)
- When I run it, it should return the bottle and cap together.
Here is the above description translated into code:
1
2
3
function bottleCapper(bottle, cap) {
return bottle + cap;
}
The plus operator, +
, acts in two different ways:
- It adds two numbers together
- It concatenates (joins) two strings together
Practice: Running a Function
In the above code, we’ve “built our machine” — we’ve defined our function. Let’s now run it. To run our machine, we need to turn it on, and give it the raw materials to use.
- To turn it on, we simply start a new line with the machine name:
bottleCapper
- To run the machine, we give it the raw materials inside parentheses:
(“green bottle”, “white cap”)
The function execution will look like this:
bottleCapper("green bottle", "white cap");
That’s all there is to it! We’ve successfully simulated a simple machine in JavaScript.
However, there are still a few more concepts we need to understand. The first one is the difference between function parameters and function arguments in JavaScript.
What is the Difference Between Function Parameters and Function Arguments in JavaScript?
Parameters are simply the ‘slots’, the placeholders for inputs that a function should receive.
Arguments are the specific values of JavaScript data types that we give those slots when we run a function.
This begs the question: just what data types are there in JavaScript? Put differently, what are the accepted values for arguments in JavaScript function calls?
JavaScript Data Types
A JavaScript function can accept any data type that exists in JavaScript. There are two distinct groups of data types in JavaScript:
- Primitive types (primitives)
- The one complex type (objects)
Primitive data types in JavaScript
Here is a simple mnemonic for you: JavaScript SNUBS primitives.
“SNUBS”, as in:
- strings
- numbers
- null
- undefined
- booleans
- symbols
So, there are six primitive data types in JavaScript. That’s why I say that JS SNUBS PRIMITIVES. I like it better when I omit the second N. But I know it’s there.
Another interesting piece of information on primitive types: only strings have single or double quotes around them.
Anyway, besides primitive data types, JavaScript also has the one complex data type: the object.
Objects in JavaScript
Objects in JavaScript come in three flavors:
- regular, plain old objects
- arrays, and
- functions
In JavaScript, arrays and functions are just another kind of object!
Alright, this is all great, but how do we use them in functions?
Using JavaScript Data Types as Arguments when Calling Functions
Let’s define our bottleCapper function
(“machine!”) again, and then, when we call it, we’ll pass it values for each of the data types that exist in the language:
1
2
3
4
5
6
7
8
9
10
11
12
// function definition (building the "machine")
function bottleCapper(bottle, cap) {
return bottle + cap;
}
// running the function (running the "machine")
bottleCapper("green bottle", "white cap");
bottleCapper("5", 5);
bottleCapper(null,undefined);
bottleCapper(Symbol());
bottleCapper({});
bottleCapper([]);
bottleCapper(bottleCapper("green bottle", "white cap"));
Note the second time we called the function in the code above:
bottleCapper(“5” + 5);
When JavaScript needs to convert one type to another, that’s called coercion. For example, using the +
operator on a string and a number will coerce that number into a string, which will result in the string “55” being returned by the second function call above.
There are some other things to note. The first four times we called the bottleCapper
function, we passed primitive values as arguments. On the last three lines, we passed:
- an empty object: bottleCapper( {} )
- an empty array: bottleCapper( [] )
- a call to the same function: bottleCapper(bottleCapper(“bottle”, “cap”))
In the next section, let’s revise what we covered. We’ll repeat the same concepts from a slightly different angle, so that we can reinforce our understanding.
Revision: Defining, Naming, and Running Functions
In the following image, we have highlighted different sections of our bottleCapper function and the function call to the left. To the right, we have written the “translation” from JavaScript to our “machine’s diagram language”.
To reiterate, the raw materials that the machine “expects” are called PARAMETERS.
The actual raw materials that we “feed” the machine when we run it are called ARGUMENTS.
Parameters are specified in the FUNCTION DEFINITION.
Arguments are given to the function when WE RUN IT.
Naming Functions in JavaScript
The name of a function answers the question: What does it do?
Consider the following function definitions:
function sparky() {}
function johnDoe() {}
function combineTwoThings {}
The name of a function should be descriptive and short:
function joinTwoStrings(first, second)
If in doubt, favor clarity over brevity.
Conclusions
Based on all of the above, we can derive some conclusions. It’s worth it to list them, even though some of these conclusions might not be completely understandable at this point (information overload!):
- JavaScript is dynamically typed (i.e. “loosely typed”) because, among other things, functions, when called, indeed do run the code, regardless of what data type we pass them as arguments. This is not the case in some other, statically typed languages. Such languages will throw an error and refuse to run when we try to run their functions with arguments that have unexpected data types.
- We can pass any kind of value as an argument when we run a function.
- In JavaScript, if a value is not a primitive, it’s an object.
- A function’s parameter acts as a ‘slot’ that will receive a specific value when a function is called (parameters are slots, arguments are specific values).
- What we name a function, and what names we give our parameters, is important to humans. Computers don’t care (as long as we’re consistent — meaning we use the same name to define and call the same function).
- Coercion is the process of JavaScript automatically changing the data type of a certain value so that it can execute a meaningful operation on variables of different types.
Did you like the article? Do you like what you’ve learned? Then buy the book and save yourself from at least 1000 hours of suffering through basic concepts.