Functions in JavaScript – A Gentle Introduction10 min read

In some previous articles, we have been playing around with JavaScript for a while and learn some fundamental topics. Today, we are going to learn a brand new concept of JavaScript language, which is functions. Functions in JavaScript or like any other programming languages play a vital role in creating applications and usages. Grasping some crucial concepts about functions will make a huge leap in your learning JavaScript process.

But before we start, please make sure that you’ve already read the previous articles:

Defining functions and calling

Function definitions

Functions in JavaScript like many other languages are the block of code that can be used multiple times. First, let’s define what is the function and see some examples of it.

A function (or function statement, function definition) consists of the function keyword (not Function keyword because JavaScript will think you’re defining constructor in JavaScript, but don’t worry about it for now) and followed by:

  • The name of the function you want to give, you should start a function’s name by a lowercase letter with an understandable name.
  • The parameters inside parentheses separated by the commas (parameter1, parameter2, …), you can define many parameters if you want. But you should create two parameters if possible in order to easy to maintain.
  • The function statements that define the function, enclosed by the curly brackets { }.

For example, we will create a function named addNumber:

function addNumber(a, b){
    console.log(a + b);
}

Beneath we defined a function named addNumber with two parameters a and b and the statement is logged out the sum of a and b.

Calling a function

Call function below the function definition (Normally)

But the fact is this function above didn’t do anything. In order to execute this function, we need to call the function:

function addNumber(a, b){
console.log(a + b);
}
addNumber(2, 3); // Output: 5

To call or invoke the function, write the function’s name outside of the function scope (which means inside curly brackets { }) and passing arguments enclosed by parentheses if necessary. In this example above, we define two parameters so we also need to call a function with the same arguments. a equals 2 and b equals 3, respectively.

Now the question is, what the heck are parameter and argument. So basically we can explain like this:

  • Parameters are the aliases for the values that will be passed to the function when you define it.
  • Arguments are the actual values when you call or invoke a function.
Calling function above function definition – Hoisting

You can also call a function above the function definitions or it can be named function hoisting:

console.log(square(7)); // Output: 49
function square(n) { return n * n; }

Hoisting is a quite vague topic for beginners, but now you will figure it out. On this example above, the JavaScript engine will handle these lines of code like that:

function square(n) { return n * n; }
console.log(square(7));

The function declaration has been hoisted, so what’ve just happened? All the declarations (not just function, also variable declaration) in scope, regardless of where are their positions, they will be moved to the top while JavaScript engine handles theme after printing out the output, which called hoisting.

As I annotated above, all the declarations will be moved to the top, including variable declaration, now let’s do another example:

a = 7;
var a;
console.log(a);

So, can you guess what will be printed out in the console? undefined or 7? (You can see a lot of 7 here because I just love this number xD) The answer is 7, here is what happened inside JavaScript engine:

var a;
a = 7;
console.log(a);
// 7

The variable declaration has been hoisted to the top (like function declaration) so we still get the desired output.

NOTE: Remember, hoisting just happens with variable declarations and function declarations. Assignments such as variable assignment, function expression assignment will not be hoisted, consider this code:

console.log(x);
var x = 7; // undefined

Some people guess the output will be 7, others think it will throw ReferenceError because variable a is used before declaring. Yet, you can see the output, undefined. Now let’s split it up, this code will be handled like that:

var x;
console.log(x);
x = 7;

All the function or variable declarations will be hoisted to the top of the scope (in this case is the global scope), but not the assignment. JavaScript engine will look up this code like that. We can see, we have a variable named x but didn’t give it a value and right after we log x result and then we assign x to 7. Which leads to undefined.

Function Expression

Anonymous Functions

Another way to create a function is function expression which means the word “function” is not the very first thing of a statement, you will assign a function to a variable, look at the example below:

var calculus = function multiply(a, b){return a * b};
console.log(calculus(2, 3)); // Output: 6
console.log(multiply(2, 3)); // Error, multiply is not defined.

With function expression, it’s better if you create a function without giving it a name – or it can be called the anonymous function to avoid errors:

var divide = function(a, b){
return a / b;
}
console.log(divide(14, 2); // Output: 7
Function Expressions with a function’s name

In most cases, you don’t need to name a function with function expression. Like the example above, it can occur in an error. However, a name in your function should be provided if you need to refer function itself or call it inside its function:

var factorial = function fac(n) {
  if (n <= 1) {
    return 1;
  }
  else {
    return n * fac(n - 1);
  }
}
console.log(factorial(5)); // 120

The function has been called and executed inside itself and it called recursion.

Return Keyword

The functions above work well. Inside the function’s statement, as you can observe, we didn’t use console.log, instead of that we used the return keyword which means when a return statement is called in a function, the execution of this function is stopped. To envision, look at the example underneath:

var checkWhetherLessThanTen = function (a) {
  if (a < 4) {
    return "This number is less than 4";
  }
  else if (a < 7) {
    return "This number is less than 7";
  }
  else if (a < 9) {
    return "This number is less than 9";
  }
  else if (a > 10) {
    return "This number is greater than 10";
  }
}
console.log(checkWhetherLessThanTen(2));
// Output: This number is less than 4

This function will return `This number is less than 4` because the condition in the if statement is true and inside it using return keyword, then everything below will not be executed even though the number we passed when we call a function is also less than 7, 9, etc…

Function hoisting does not work with function expressions

Hoisting function will work with function definition but it does not work with function expression:

console.log(square(7)); // TypeError: square is not a function
var square = function(n) { 
  return n * n; 
}

NOTE: The difference between function declaration and function expression is, the word “function” is the very first thing of a statement then it’s a function declaration, otherwise it’s function expression. Look at another example of function expression below:

(function foo(){
	var a = 7;
	console.log(a)
})(); // 7

As can be observed, this function is wrapped by pair ( ), “function” keyword is not the very first thing of this statement. Thus, we can confirm that it’s a function expression. This function is being called right after we have defined function expression. There is a term for this kind of function, which is IIFE (Invoking Function Expressions Immediately).

Function scope

I’ve mentioned about function scope in the very first example of calling a function. For more specific, variables defined inside a function enclosed with curly brackets { } cannot be accessed anywhere outside of this function:

function myTest() {
  var bar = "foo";
  console.log(bar);
}
myTest(); // foo
console.log(bar); // bar is not defined

However, a function can access all variables and functions defined inside the scope in which it is defined:

function factorial() {
  function fac(n) {
    if (n <= 1) {
      return 1;
    } else {
      return n * fac(n - 1);
    }
  }
  return fac(5);
}
factorial(); // 120

As can be observed, the outer function or the global function has another function inside it called the nested function or inner function. Even we return fac(5) which means it outside of the inner function but we still can execute and get the result.

The function defined as a global scope that not be nested by another function can access all the global variables in global scopes, for instance:

var a = "Today is ";
var b = "Thursday!";
function today(){
    return a + b;
}
today(); // Today is Thursday!

A function defined inside another function can also access all variables defined in its outer function or parent function and any other variables to which the parent function has access:

var player = "Simon";
function getScore() {
  var firstScore = 3;
  var secondScore = 4;
  function simonScore() {
    return player + " scored " + (firstScore + secondScore);
  }
  return simonScore();
}
getScore();
// Simon scored 7

We have a global variable named player, which means it can be accessed anywhere in our program. Then, we defined a function named getScore which has two local variables and also has one nested function. Inside the inner function, simonScore, we access the player variable (first, it’s the variable globally, second, it has been accessed by the parent function, so the inner function). Also, you can see, the simonScore function can access the variables which have been declared in the parent function and add them together. And the final output, as you probably guess, Simon scored 7.

The inner function or nested function also can nest another function inside it and even multi-nested:

function A(x) {
  function B(y) {
    function C(z) {
      console.log(x + y + z);
    }
    C(4);
  }
  B(2);
}
A(1) // Output: 7

Closures

On some of the examples above and in function scope section, we’ve been talking about the terms like outer function or parent function, inner function or nested function. Actually, we have already exposed to Closures in JavaScript. Closures are one of the most powerful features in JavaScript programming language allowing programmers to write better code, creative and concise.

So, what exactly are closures in JavaScript? A closure is an inner function or the nested function which defined inside the outer function or parent function. The inner function (closure) has 3 powerful chains:

  • It can access its own scope (the function or variable defined between its curly brackets).
  • It can access the outer variable, parameters… which defined in the outer function.
  • And of course, it also can access to the global variable.
var whoIsRick = "Rick is a mad and genius scientist.";
function rickInfo(firstName, lastName) {
    var name = "His name is ";
    // this inner function has access to its own scope, the outer function's variables, including the parameter and the global variable
    function showName() {
        return name + firstName + " " + lastName + ", " + whoIsRick;
    };
    return showName();
}
rickInfo('Rick', 'Sanchez');
// Output: His name is Rick, Rick is a mad and genius scientist.

However, the outer function does not have the same power as the inner function, it cannot access variables defined inside the inner function.

Name conflict in Closure

Sometimes when you define names of variables or arguments in the inner block but it has the same name with outer function, this called name conflict. In inner-most scope has the highest precedence, and the outer scope has the lowest precedence. Consider the following code:

function outside() {
  var number = 5;
  function inside(number) {
    return number * 2;
  }
  return inside(10);
}
outside(); // 20 not 10.

Conclusion

From now on, you definitely have a taste with function in JavaScript. Try more practices to understand this deeper – because it is a very essential part of JavaScript programming language. This article is not to cover all of the functions and concepts related. We will talk more about the function such as call-back function, higher-order functions, default parameters, rest parameters, arrow function and more in the next few chapters. Once again, hope this article was useful and practical. Happy coding!

Previous Article
Next Article

Categories

Archives