We’ve already figured out that programs consist of commands that are executed in order. Top-down. Thus, we can provide the computer with a set of instructions (commands). It will execute them and we will get the expected result.

To give you a real-world example, let’s find a phone number in a “directory” of a million entries.

But let’s imagine that we have not one directory, but 5. Then, we would need to repeat the entire sequence of commands for each directory. The program would be 5 times longer.

— Well, what can you do, you need to find something…

— Of course, you need to find, but there may be more even more directories. What will we do if there are 100 of them? Or 1000?

— Sounds like you want to tell me about some very convenient way to avoid repetition?

— Yes, there is. In order to avoid code duplication and to write clean code, there are several tricks. The first of them is called a function.

The idea is simple. We highlight a part of the program and give it a name. Let’s recall the linear search algorithm from the previous lecture:

open the directory on the first page
look through all entries from top to bottom
if a match is found (Jack Jones)
  we call the found number
else
  go to the next entry
repeat until we run out of pages

We can give it a name like linearSearch. Now, when we need to search for the phone in the directory, we will no longer repeat all the commands. It will suffice to write linearSearch(phoneBook, name).

— It seems clear, but what are the phoneBook and name?

— These are function arguments. Or, in other words, the values that we pass into the function. After all, for the code (set of commands) to be used over and over again, it must be universal, that is, be able to work with different data. In our case, we give the search algorithm a phone book and a name to search for.

— How does it look in JavaScript?

— It’s too early for you to implement search in JavaScript, but let’s try to write a simple function that takes the user’s first and last name as parameters and greets him.

If the user’s name is Peter Peterson, then the hello command would look like this:

console.log('Hello, Peter Peterson!');

To store this code in a function, we need to create a variable (or a constant):

const sayHello;

Now, all that remains is to bind the function that greets the user with the constant sayHello. To do this, we will wrap all the commands inside the function in the construction () => {...}. Instead of three dots, we’ll write our commands, add an “arrow” (=>) and the function will be ready!

const sayHello = () => {console.log ('Hello, Peter Peterson!'); };

— Ok, but we planned to greet a user with any name. It would be strange if John Johnson came to us, and we said to him Hello, Peter Peterson!.

— That’s right, but let’s start in order.

Parameters and arguments

— It is very convenient to be able to encapsulate some pieces of code into a function. It’s like a plane that flies on the New York - London route. The flight can involve many different people and technology. But that doesn’t bother us much. We just know that if we board this flight in New York, we will be in London in a few hours.

But the real power comes from functions that can change their behavior depending on the current situation and need. It’s like a private jet. You go to the pilot, give him a note with the coordinates, board, and wait for you to be delivered to your destination.

In this case, you do not need to maintain 100 different planes in all major cities in the world. One will be enough. After all, in fact, you are simply interested in a flight from point A to point B, and it would be most convenient to announce your desire immediately before departure.

Let’s give two key definitions. Functions have parameters and arguments.

  • Parameters are variables that we specify when we define a function.
  • Arguments are the values that we pass to the function when it is called.

After we call the function, parameters are initialized with the values of the arguments.

To be honest, it won’t be the end of the world if you suddenly confuse these two terms. It’s just important to understand that you can pass some data (arguments) into the function. And, inside the function, you can implement some kind of algorithm, even without having data but relying only on parameters.

— Can I have an example?

— Sure. Look:

const addAndPrint = (x, y) => {
  console.log(x + y);
}

We have created an addAndPrint function that adds two numbers and prints the result to the screen.

Notice how in this example the statement console.log(x + y); is placed two spaces further to the right of the first line where we’ve declared a function addAndPrint. It’s called indentation.

Indentation is a concept that makes your code more readable. We’ll revisit this concept later, but you can start noticing it right now.

The variables x and y are parameters. They don’t have a value when the function is declared, but it will appear when the function is called.

Please note that we do not use the keywords let and const here, but simply write the parameters in parentheses separated by commas. Their number is unlimited.

Using the functions and return value

— In addition to passing arguments to a function, a value can also be returned from a function.

This can be done using the return keyword. It is important that a function can have only one return value, as opposed to parameters, which are not limited by the JavaScript language.

For example, we could implement a function that simply adds two numbers.

const add = (x, y) => {
  return x + y;
}

Or another function that adds an exclamation mark to any passed value.

const addExclamationMark = (s) => {
  return s + '!';
}

— I see. Something like a formula, where you substitute the variables with the actual data and then return the result.

— If a function returns some value, then it is convenient to store it in a variable. Let’s use the add function from the previous example:

const sum = add (5, 3);    // sum = 8

When you’re thinking about what can be used as an argument, you’re not limited to “ordinary” numbers, but also other variables, constants, or even the returned result of other functions.

What is the eventual value of result here?

const a = 1;
const b = 2;
const c = 5;
const d = 10;

const result = sum(sum(a, b), sum (c, d));

— Oh … If I understand everything correctly, then we can simplify the expression to sum (3, 15). Then the answer is 18!

— Right! Going back to the first and last name example in the function declaration, we also need to add the name and surname parameters. We’ll also slightly change the output to the screen.

const sayHello = (name, surname) => {
  console.log('Hello, ' + name + ' ' + surname + '!');
};

So, to create a function we need:

  1. Parentheses, in which we can specify the parameters of the function (name, surname).
  2. Arrow => to separate the parameters of the function and the list of commands (body) of the function.
  3. Curly braces {}, inside of which we will place the body of the function.
  4. The keyword return, followed by the return value.

You can think of a function as a subroutine. After we call it, the instructions that make up the function body will be executed in order, from top to bottom.

— How can I call the function and what’s the meaning of 'Hello, ' + name + ' ' + surname + '!' that you wrote inside of the parenthesis after the console.log?

— To call a function, you need to write its name, add two parentheses, and a list of arguments.

  • console.log('Hello, world!') - we’re calling the function console.log with a single argument 'Hello, world!'
  • add(2, 2) - we’re calling the function add with arguments 2 and 2
  • sayHello() - we’re calling the function sayHello without arguments

Also, a function can be declared in one file and used in another. Just like any other constant.

//functions.js
export const sayHello = (name, surname) => {
  console.log('Hello, ' + name + ' ' + surname + '!');
};
//solution.js
import { sayHello } from './functions.js'

sayHello('Jack', 'Jackson'); // Hello, Jack Jackson!

To display a greeting to the user, we use string concatenation (addition). It is done with the + operator, which glues the second line to the end of the first one.

Note that if we just write console.log('Hello, name surname!'); this is what will be printed to the screen. The computer cannot “guess” that you wanted to replace name and surname with the values passed to the function and will just print Hello, name surname!.

— What happens if we don’t pass any arguments to the function and just write sayHello()? Will the program break?

— No, it won’t break. Inside the sayHello function, the values of the name and surname variables will appear as undefined. This is a special value for the variables that were not initialized. For console.log and the + operator, this is not a problem. The expression 'Hello, ' + name + ' ' + surname + '!' becomes Hello, undefined undefined!. And this is the message that will be displayed on the screen.