Posted on 16 May 2019 at 15:00 PM
In this JavaScript functions basics tutorial we'll be looking at how to create a function, passing parameters into functions, higher order functions, anonymous functions and much more.
A function is packaged code that can be reused many times. For example, say you are an accountant and you must work out how much to pay each member of staff based upon their hourly wage and the numbers of hours they've worked. Done manually this would take some time (depending upon how many staff you had) - you could, however, write a function that would do this repetitive task for you.
To write a function, you start by using the JS keyword 'function' then provide a name for your function, follow with parentheses, brackets and then your logic for you function.
function two_plus_two()
{
return 2+2;
}
console.log(two_plus_two()); # returns 4
Note that we used the JS keyword 'return' to pass the result back the call. In this case we just logged it to the console, but you could also assign it to a variable.
To make functions more dynamic, you can add parameters which allows you to pass data into the function. Using our earlier example we can forecast a staff members pay by creating a function which accepts an hourly wage and number of hours.
function staff_pay(hours_worked, hourly_pay)
{
return hourly_pay * hours_worked;
}
console.log(staff_pay(40, 10)); # returns 400
let Jamie = staff_pay(40, 10);
console.log(Jamie); # returns 400
Note how created a variable 'Jamie' and assign to it the returned value from the function call. We can also provide a default parameter - this means if we do not pass any data to the function, it will use the default. For example, say 90% of staff are on the same hourly wage you could use a default value for this and specify a wage when an employee has a unique hourly wage.
function staff_pay(hours_worked, hourly_pay=10)
{
return hourly_pay * hours_worked;
}
console.log(staff_pay(40)); # returns 400
let Jamie = staff_pay(40, 15);
console.log(Jamie); # returns 600
When a function is executed and hits a 'return' keyword, anything after the return will not be executed. In some cases you might want to have multiple returns using conditional logic. For example, say any staff member that works over 40 hours per week receives pay and a half for the overtime hours, otherwise they receive their normally hourly wage.
function staff_pay(hours_worked, hourly_pay)
{
if (hours_worked > 40)
{
let standard_pay = 40 * hourly_pay;
let over_time = (hours_worked - 40) * (hourly_pay * 1.5);
return standard_pay + over_time;
}
return hourly_pay * hours_worked;
}
console.log(staff_pay(45, 10));
It possible to return a value of a function inside another function which is known as a 'helper' function. For example, say we wanted to convert hours into seconds. For the basis of this exercise I have broken in into two functions - the first converting hours to minutes and the second converting hours to seconds. Note how the function returns the result of another function call.
function minutes_to_seconds(minutes)
{
let seconds = minutes * 60;
return seconds;
}
function hours_to_minutes(hours)
{
let minutes = hours * 60;
return minutes_to_seconds(minutes);
}
console.log(hours_to_minutes(8));
Function expressions typically have no name, (functions with no name are called anonymous function) and are often stored in a variable. Lets take a look at an example.
const bin_day = function(day)
{
if (day == 'thursday')
{
console.log('Take bins out');
}
else
{
console.log('Do not take bins out');
}
}
bin_day('thursday');
bin_day('wednesday');
Note that we are assigning the variable to the function - it is a reference to the function and thus we can invoke the function by calling the variable with parenthesis and passing a parameter.
As of ES6, arrow function syntax was introduced. This removed the requirement to use the keyword 'function' in replacement for '=>'. Using our function expression above as an example, we remove the keyword 'function' add the parameters and then use '=>' followed by the logic inside of brackets.
const bin_day = (day) =>
{
if (day == 'thursday')
{
console.log('Take bins out');
}
else
{
console.log('Do not take bins out');
}
}
bin_day('thursday');
bin_day('wednesday');
Arrow syntax goes even further depending upon the parameters required and if the line spans multiple lines.
If there is only one parameter, the function does not parenthesis. The other two must have parenthesis.
const function_name = () => {};
const function_name = param_one => {}; # functions taking a single parameter do not parenthesis
const function_name = (param_one, param_two) => {};
If the code spans a single line, you do not need to implicitly tell the function to return a result - it does it on its own. If the code spans multiple lines then a return keyword must be used (if you require the result to be returned).
const function_name = param_one => param_one + param_one;
const function_name = param_one =>
{
const sum = param_one + param_one;
return sum;
}
Scope refers to where variables can be accessed from within some code. Some variables, known as 'global scope' can be accessed from anywhere within your program, whereas others will only be accessible within a given block of code (inside of brackets like a function, condition statement etc.)
Block scope means variables can only be accessed via the block - that is anything with the brackets. For example, take a function with a variable declared inside the function. This has block scope. If you try to access this variable outside of the block you will get an error.
function test_scope()
{
let block = 'variable with block scope';
console.log(block);
}
test_scope(); # returns 'variable with block scope'
console.log(block); # returns error
Variables declared outside of a blocks. They can be accessed anywhere in the program including inside of blocks.
let global_scope = 'this variable is global scope';
function test_scope()
{
console.log(global_scope);
}
test_scope(); # logs 'this variable is global scope'
console.log(global_scope); # logs 'this variable is global scope'
Scope pollution is the concept of variables over writing one another - say you have a global variable which is accidently reassigned inside a block.
let scope_pollution = 'this variable is global scope';
function test_scope()
{
scope_pollution = 'our variable has changed!'
console.log(scope_pollution);
}
console.log(scope_pollution);
test_scope();
console.log(scope_pollution);
A higher order function is a function that either accepts another function as a parameter, returns a function or both. When we pass a function in as a parameter we do not invoke the function - invoking would evaluate the return of that function call. Instead we pass in the function with no parenthesis and invoke inside higher order function.
const timeFuncRuntime = funcParameter =>
{
let t1 = Date.now();
funcParameter();
let t2 = Date.now();
console.log(t2 - t1);
}
function time_trial()
{
for (let i =0; i < 1000; i++)
{
console.log(i);
}
}
timeFuncRuntime(time_trial);
Note, we could have also assigned a function to a variable and passed the variable through the function in the same manner. As the variable if referencing the function it would still be invoked in the higher order function.
const timeFuncRuntime = funcParameter =>
{
let t1 = Date.now();
funcParameter();
let t2 = Date.now();
console.log(t2 - t1);
}
const time_trial = function()
{
for (let i =0; i < 1000; i++)
{
console.log(i);
}
}
timeFuncRuntime(time_trial);