JavaScript Terms Part 1
I think many programmers would agree that learning JavaScript is one of the most challenging tasks compared to learning other languages.
Many terms are, for the most part, unheard of in other languages. Among them are terms like higher order functions, hoisting, truthy, falsey, coercion, currying and closures.
Because these things exist in JavaScript, it can be very confusing to learn JavaScript after learning other languages. Most of the time, to go from one language to another all you have to do is translate your syntax knowledge from language a to language b. But that is far from true with JavaScript.
In addition, JavaScript behaves in different ways than the way most other languages behave in certain scenarios. Some examples of that are the use the key word “this” as well as when comparing values.
Because of these concepts, you can’t just use a syntax cheatsheet to learn JavaScript. In fact, you have to throw away much of what you already know and learn it JavaScript from the ground up. Do not make the mistake that many programmers make and just hack your way around it. You will spend many hours of frustration if you do.
This not only causes confusion for seasoned programmers, but it also makes JS harder to learn as a first language.
I want to write a series on on these topics and today I am going to start with higher order functions.
Functions Are First Class Citizens
You may have heard that functions are first class citizens in JavaScript. In most other languages functions and even methods are not first class citizens. They are just a process that can be invoked. In other languages functions require extra work to handle the scenarios below:
- store function as a variable
- pass a function as an argument
- return a function from a function
- extend a function with functionality
- decorate a function or simplify a function
- declare a function anonymously
- invoke a function immediately after declaring it
In JavaScript functions are objects. If you remember, in JavaScript you can extend an objects behavior and state by adding attributes and methods.
Because functions are Objects they can be handled just like any other data type instance. You can stored them in variables, pass them to other funcions, return them from functions and even add state and additional functionality.
In this post we will focus on the aspect of storing them in variables and passing them around to other functions. The concepts in this post are essential for understanding the concept of higher-order functions.
Function Stored as a Variable
Let’s start with the most common scenario, to store a function as a variable. You may have seen a function declared anonymously and stored in a variable.
let add = function(a, b){
return a + b;
}
In the example above we have created a variable named add and assigned a function to it that returns the sum of the parameters a and b.
Later we can invoke the function by its variable name and using parentheses along with parameters to invoke it.
let sum = add(5,10);
Since the function is stored in a variable, we can also pass it to other functions
function outputSum(a, b, mathOperation){
console.log(mathOperation(a, b);
}
outputSum(5, 10, mathOperation);
The function outputSum above is an example of a higher-order function because it takes a function as a parameter. It then invokes that function to produce the result.
You may be wondering why I named the parameter mathOperation. That is because the output sum may accept other 2 parameter functions such as multiply or divide.
let multiply = function(a, b){
return a * b;
}
outputSum(5, 10, multiply);
Notice that the outputSum function requires no changes yet it will behave differently depending on the function passed in.
When passing functions as parameters these are sometimes referred to as callbacks. Callbacks are very common in non blocking code. The reason is that the invoked function does not necessarily know what to do with the results and instead provides an opportunity for the caller to define that in the call back.
When Functions Return Other Functions
Sometimes functions return other functions. There are many reasons why a function must return a function instead of a concrete result.
function getPortionCalculator(amount){
return function(contributors){
return amount/contributors;
}
}
let calculate = getPortionCalculator(1000);
let portion = calculate(10);
In the example above the function getPortionCalculator returns another function. That function can then be used to calculate the amount for each contributor. This is another example of a higher-order function because it returns a function.
Don’t concern yourself too much with the real world uses for this type of coding. You will run into them soon enough if once you start coding in JavaScript. You will also need to understand this concept in order learn other more advanced concepts.
Two Ways to Declare a Function
You may have noticed that I declared a function two different ways.
let doSomething = function(){
//code to do something here
}
In the code above I declare a variable and store a function in it.
In the code below I simply name the function.
function doSomething(){
//do something here
}
So… which way should you use and when? That is an excellent question. Let’s go back and look at an earlier example.
outputSum(4, 10, function(a, b){
return a + b;
}
}
Notice how I declared the function right in the location where I passed variable earlier. Sometimes the definition of the function can be pretty long. It can help to clean up the code by storing the function in a variable and then passing the variable instead of declaring the function inline. It would make the code cleaner.
Another consideration to keep in mind is hoisting. We are not going to talk about hoisting in detail in this post. However, it is important to know that when you declare a function and store it in a variable the function is not available up higher in the code.
That is because even though the hoisting occurs, and the variable exists, the function has not yet been assigned to it. The variable exists but it has a value of undefined.
function doSomething(){
foo();
}
doSomething();
var foo = function(){
console.log("foo");
}
The function above will result in an error. The error will indicate that foo is not a function. Notice that it does not say that it is not defined but rather that it is not a function. The reason for that is hoisting. This what the code looks like to the compiler (or JS engine).
var foo;
function doSomething(){
foo(); //foo is undefined
}
doSomething(); // calls foo before being defined
//foo is defined after do something tried to call it
foo = function(){
console.log("foo");
}
Take the code example below and you notice it is not much different. However, the function below will run and output “foo” to the console. Hopefully you can tell the difference between the two ways of declaring a function from this example.
function doSomething(){
foo();
}
doSomething();
function foo(){
console.log("foo");
}
Summary
JavaScript is different in many ways than most other languages and specially static languages. In this session we covered one small portion of the many terms that complicate JavaScript, higher order functions. Please subscribe so that you can get the notifications when I public the upcoming posts related to JavaScript terms.