JavaScript Function Part One
Last updated
Was this helpful?
Last updated
Was this helpful?
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:
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).
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.
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.
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:
The plus operator, +, acts in two different ways:
It adds two numbers together
It concatenates (joins) two strings together
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:
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.
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?
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)
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 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?
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:
Note the second time we called the function in the code above:
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.
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.
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.
The name of a function answers the question: What does it do?
Consider the following function definitions:
The name of a function should be descriptive and short:
If in doubt, favor clarity over brevity.
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.